added sm_dump_handles command for tracking down Handle leaks... more to come someday
authorDavid Anderson <dvander@alliedmods.net>
Thu Jun 07 02:36:54 2007 +0000 (2007-06-07)
changeset 900b38c83f9d526
parent 899 af4da125603b
child 901 db978c2819e6
added sm_dump_handles command for tracking down Handle leaks... more to come someday
core/sm_srvcmds.cpp
core/systems/HandleSys.cpp
core/systems/HandleSys.h
core/systems/PluginSys.cpp
core/systems/PluginSys.h
     1.1 --- a/core/sm_srvcmds.cpp	Thu Jun 07 02:26:06 2007 +0000
     1.2 +++ b/core/sm_srvcmds.cpp	Thu Jun 07 02:36:54 2007 +0000
     1.3 @@ -15,6 +15,7 @@
     1.4  #include "sm_srvcmds.h"
     1.5  #include "sm_version.h"
     1.6  #include "sm_stringutil.h"
     1.7 +#include "HandleSys.h"
     1.8  
     1.9  RootConsoleMenu g_RootMenu;
    1.10  
    1.11 @@ -254,3 +255,24 @@
    1.12  {
    1.13  	g_RootMenu.GotRootCmd();
    1.14  }
    1.15 +
    1.16 +CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
    1.17 +{
    1.18 +	if (engine->Cmd_Argc() < 2)
    1.19 +	{
    1.20 +		g_RootMenu.ConsolePrint("Usage: sm_dump_handles <file>");
    1.21 +		return;
    1.22 +	}
    1.23 +
    1.24 +	const char *arg = engine->Cmd_Argv(1);
    1.25 +	FILE *fp = fopen(arg, "wt");
    1.26 +	if (!fp)
    1.27 +	{
    1.28 +		g_RootMenu.ConsolePrint("Could not find file \"%s\"", arg);
    1.29 +		return;
    1.30 +	}
    1.31 +
    1.32 +	g_HandleSys.Dump(fp);
    1.33 +
    1.34 +	fclose(fp);
    1.35 +}
     2.1 --- a/core/systems/HandleSys.cpp	Thu Jun 07 02:26:06 2007 +0000
     2.2 +++ b/core/systems/HandleSys.cpp	Thu Jun 07 02:36:54 2007 +0000
     2.3 @@ -15,6 +15,7 @@
     2.4  #include "HandleSys.h"
     2.5  #include "ShareSys.h"
     2.6  #include "PluginSys.h"
     2.7 +#include "ExtensionSys.h"
     2.8  #include <assert.h>
     2.9  #include <string.h>
    2.10  
    2.11 @@ -899,3 +900,52 @@
    2.12  
    2.13  	return true;
    2.14  }
    2.15 +
    2.16 +void HandleSystem::Dump(FILE *fp)
    2.17 +{
    2.18 +	fprintf(fp, "%-10.10s\t%-20.20s\t%-20.20s\n", "Handle", "Owner", "Type");
    2.19 +	fprintf(fp, "---------------------------------------------\n");
    2.20 +	for (unsigned int i=1; i<=m_HandleTail; i++)
    2.21 +	{
    2.22 +		if (m_Handles[i].set == HandleSet_Freed
    2.23 +			|| m_Handles[i].set == HandleSet_Identity)
    2.24 +		{
    2.25 +			continue;
    2.26 +		}
    2.27 +		/* Get the index */
    2.28 +		unsigned int index = (m_Handles[i].serial << 16) | i;
    2.29 +		/* Determine the owner */
    2.30 +		const char *owner = "UNKNOWN";
    2.31 +		if (m_Handles[i].owner)
    2.32 +		{
    2.33 +			IdentityToken_t *pOwner = m_Handles[i].owner;
    2.34 +			if (pOwner == g_pCoreIdent)
    2.35 +			{
    2.36 +				owner = "CORE";
    2.37 +			} else if (pOwner == g_PluginSys.GetIdentity()) {
    2.38 +				owner = "PLUGINSYS";
    2.39 +			} else {
    2.40 +				CExtension *ext = g_Extensions.GetExtensionFromIdent(pOwner);
    2.41 +				if (ext)
    2.42 +				{
    2.43 +					owner = ext->GetFilename();
    2.44 +				} else {
    2.45 +					CPlugin *pPlugin = g_PluginSys.GetPluginFromIdentity(pOwner);
    2.46 +					if (pPlugin)
    2.47 +					{
    2.48 +						owner = pPlugin->GetFilename();
    2.49 +					}
    2.50 +				}
    2.51 +			}
    2.52 +		} else {
    2.53 +			owner = "NONE";
    2.54 +		}
    2.55 +		const char *type = "ANON";
    2.56 +		QHandleType *pType = &m_Types[m_Handles[i].type];
    2.57 +		if (pType->nameIdx != -1)
    2.58 +		{
    2.59 +			type = m_strtab->GetString(pType->nameIdx);
    2.60 +		}
    2.61 +		fprintf(fp, "0x%08x\t%-20.20s\t%-20.20s\n", index, owner, type);
    2.62 +	}
    2.63 +}
     3.1 --- a/core/systems/HandleSys.h	Thu Jun 07 02:26:06 2007 +0000
     3.2 +++ b/core/systems/HandleSys.h	Thu Jun 07 02:36:54 2007 +0000
     3.3 @@ -16,6 +16,7 @@
     3.4  #define _INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
     3.5  
     3.6  #include <IHandleSys.h>
     3.7 +#include <stdio.h>
     3.8  #include "sm_globals.h"
     3.9  #include "sm_trie.h"
    3.10  #include "sourcemod.h"
    3.11 @@ -136,6 +137,8 @@
    3.12  		const HandleSecurity *pSec,
    3.13  		const HandleAccess *pAccess,
    3.14  		HandleError *err);
    3.15 +
    3.16 +	void Dump(FILE *fp);
    3.17  protected:
    3.18  	/**
    3.19  	 * Decodes a handle with sanity and security checking.
     4.1 --- a/core/systems/PluginSys.cpp	Thu Jun 07 02:26:06 2007 +0000
     4.2 +++ b/core/systems/PluginSys.cpp	Thu Jun 07 02:36:54 2007 +0000
     4.3 @@ -1961,3 +1961,13 @@
     4.4  		}
     4.5  	}
     4.6  }
     4.7 +
     4.8 +CPlugin *CPluginManager::GetPluginFromIdentity(IdentityToken_t *pToken)
     4.9 +{
    4.10 +	if (pToken->type != g_PluginIdent)
    4.11 +	{
    4.12 +		return NULL;
    4.13 +	}
    4.14 +
    4.15 +	return (CPlugin *)(pToken->ptr);
    4.16 +}
     5.1 --- a/core/systems/PluginSys.h	Thu Jun 07 02:26:06 2007 +0000
     5.2 +++ b/core/systems/PluginSys.h	Thu Jun 07 02:36:54 2007 +0000
     5.3 @@ -362,6 +362,8 @@
     5.4  	 */
     5.5  	void AddFunctionsToForward(const char *name, IChangeableForward *pForward);
     5.6  
     5.7 +	CPlugin *GetPluginFromIdentity(IdentityToken_t *pToken);
     5.8 +
     5.9  private:
    5.10  	LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
    5.11  
    5.12 @@ -398,6 +400,7 @@
    5.13  	 * Caching internal objects
    5.14  	 */
    5.15  	void ReleaseIterator(CPluginIterator *iter);
    5.16 +public:
    5.17  	inline IdentityToken_t *GetIdentity()
    5.18  	{
    5.19  		return m_MyIdent;