added sm_dump_handles command for tracking down Handle leaks... more to come someday
added sm_dump_handles command for tracking down Handle leaks... more to come someday
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;