Move sm_dump_handles to core/logic.
This commit is contained in:
@@ -1066,11 +1066,23 @@ bool HandleSystem::TryAndFreeSomeHandles()
|
||||
return scripts->UnloadPlugin(highest_owner);
|
||||
}
|
||||
|
||||
void HandleSystem::Dump(HANDLE_REPORTER rep)
|
||||
static void rep(const HandleReporter &fn, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buffer[1024];
|
||||
|
||||
va_start(ap, fmt);
|
||||
ke::SafeVsprintf(buffer, sizeof(buffer), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fn(buffer);
|
||||
}
|
||||
|
||||
void HandleSystem::Dump(const HandleReporter &fn)
|
||||
{
|
||||
unsigned int total_size = 0;
|
||||
rep("%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
|
||||
rep("--------------------------------------------------------------------------");
|
||||
rep(fn, "%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
|
||||
rep(fn, "--------------------------------------------------------------------------");
|
||||
for (unsigned int i = 1; i <= m_HandleTail; i++)
|
||||
{
|
||||
if (m_Handles[i].set != HandleSet_Used)
|
||||
@@ -1141,16 +1153,16 @@ void HandleSystem::Dump(HANDLE_REPORTER rep)
|
||||
if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
|
||||
|| !bresult)
|
||||
{
|
||||
rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, "-1");
|
||||
rep(fn, "0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, "-1");
|
||||
}
|
||||
else
|
||||
{
|
||||
char buffer[32];
|
||||
ke::SafeSprintf(buffer, sizeof(buffer), "%d", size);
|
||||
rep("0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
|
||||
rep(fn, "0x%08x\t%-20.20s\t%-20.20s\t%-10.10s", index, owner, type, buffer);
|
||||
total_size += size;
|
||||
}
|
||||
}
|
||||
rep("-- Approximately %d bytes of memory are in use by Handles.\n", total_size);
|
||||
rep(fn, "-- Approximately %d bytes of memory are in use by Handles.\n", total_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
#include <IHandleSys.h>
|
||||
#include <stdio.h>
|
||||
#include <sm_namehashset.h>
|
||||
#include <am-string.h>
|
||||
#include <amtl/am-string.h>
|
||||
#include <amtl/am-function.h>
|
||||
#include "common_logic.h"
|
||||
|
||||
#define HANDLESYS_MAX_HANDLES (1<<15)
|
||||
@@ -111,7 +112,7 @@ struct QHandleType
|
||||
}
|
||||
};
|
||||
|
||||
typedef void (HANDLE_REPORTER)(const char *str, ...);
|
||||
typedef ke::Lambda<void(const char *)> HandleReporter;
|
||||
|
||||
class HandleSystem :
|
||||
public IHandleSys
|
||||
@@ -163,7 +164,7 @@ public: //IHandleSystem
|
||||
const HandleAccess *pAccess,
|
||||
HandleError *err);
|
||||
|
||||
void Dump(HANDLE_REPORTER rep);
|
||||
void Dump(const HandleReporter &reporter);
|
||||
|
||||
/* Bypasses security checks. */
|
||||
Handle_t FastCloneHandle(Handle_t hndl);
|
||||
|
||||
@@ -27,10 +27,15 @@
|
||||
#include "RootConsoleMenu.h"
|
||||
#include <amtl/am-string.h>
|
||||
#include <sourcemod_version.h>
|
||||
#include <ISourceMod.h>
|
||||
#include <bridge/include/CoreProvider.h>
|
||||
#include "HandleSys.h"
|
||||
|
||||
RootConsoleMenu g_RootMenu;
|
||||
|
||||
// Some top-level commands that are just thrown in here.
|
||||
static bool sm_dump_handles(int client, const ICommandArgs *args);
|
||||
|
||||
RootConsoleMenu::RootConsoleMenu()
|
||||
{
|
||||
}
|
||||
@@ -49,6 +54,9 @@ void RootConsoleMenu::OnSourceModStartup(bool late)
|
||||
{
|
||||
AddRootConsoleCommand3("version", "Display version information", this);
|
||||
AddRootConsoleCommand3("credits", "Display credits listing", this);
|
||||
|
||||
bridge->DefineCommand("sm_dump_handles", "Dumps Handle usage to a file for finding Handle leaks",
|
||||
sm_dump_handles);
|
||||
}
|
||||
|
||||
void RootConsoleMenu::OnSourceModAllInitialized()
|
||||
@@ -232,3 +240,45 @@ void RootConsoleMenu::OnRootConsoleCommand(const char *cmdname, const ICommandAr
|
||||
ConsolePrint(" http://www.sourcemod.net/");
|
||||
}
|
||||
}
|
||||
|
||||
static bool sm_dump_handles(int client, const ICommandArgs *args)
|
||||
{
|
||||
if (args->ArgC() < 2) {
|
||||
bridge->ConsolePrint("Usage: sm_dump_handles <file> or <log> for game logs");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(args->Arg(1), "log") == 0) {
|
||||
auto write_handles_to_game = [] (const char *str) -> void
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t len = ke::SafeSprintf(buffer, sizeof(buffer)-2, "%s", str);
|
||||
|
||||
buffer[len] = '\n';
|
||||
buffer[len+1] = '\0';
|
||||
|
||||
bridge->LogToGame(buffer);
|
||||
};
|
||||
g_HandleSys.Dump(write_handles_to_game);
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE *fp = nullptr;
|
||||
auto write_handles_to_log = [&fp] (const char *str) -> void
|
||||
{
|
||||
fprintf(fp, "%s\n", str);
|
||||
};
|
||||
|
||||
char filename[PLATFORM_MAX_PATH];
|
||||
const char *arg = args->Arg(1);
|
||||
g_pSM->BuildPath(Path_Game, filename, sizeof(filename), "%s", arg);
|
||||
|
||||
fp = fopen(filename, "wt");
|
||||
if (!fp) {
|
||||
bridge->ConsolePrint("Failed to open \"%s\" for writing", filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
g_HandleSys.Dump(write_handles_to_log);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
@@ -109,11 +109,6 @@ static void AddNatives(sp_nativeinfo_t *natives)
|
||||
g_CoreNatives.AddNatives(natives);
|
||||
}
|
||||
|
||||
static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
|
||||
{
|
||||
g_HandleSys.Dump(dumpfn);
|
||||
}
|
||||
|
||||
static void RegisterProfiler(IProfilingTool *tool)
|
||||
{
|
||||
g_ProfileToolManager.RegisterTool(tool);
|
||||
@@ -154,7 +149,6 @@ static sm_logic_t logic =
|
||||
&g_DbgReporter,
|
||||
GenerateError,
|
||||
AddNatives,
|
||||
DumpHandles,
|
||||
RegisterProfiler,
|
||||
OnRootCommand,
|
||||
CDataPack::New,
|
||||
|
||||
Reference in New Issue
Block a user