Move sm_dump_handles to core/logic.
This commit is contained in:
parent
c853050265
commit
168b779786
@ -35,7 +35,7 @@ namespace SourceMod {
|
|||||||
|
|
||||||
// Add 1 to the RHS of this expression to bump the intercom file
|
// Add 1 to the RHS of this expression to bump the intercom file
|
||||||
// This is to prevent mismatching core/logic binaries
|
// This is to prevent mismatching core/logic binaries
|
||||||
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 52;
|
static const uint32_t SM_LOGIC_MAGIC = 0x0F47C0DE - 53;
|
||||||
|
|
||||||
} // namespace SourceMod
|
} // namespace SourceMod
|
||||||
|
|
||||||
|
@ -68,7 +68,6 @@ struct sm_logic_t
|
|||||||
IDebugListener *debugger;
|
IDebugListener *debugger;
|
||||||
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
void (*GenerateError)(IPluginContext *, cell_t, int, const char *, ...);
|
||||||
void (*AddNatives)(sp_nativeinfo_t *natives);
|
void (*AddNatives)(sp_nativeinfo_t *natives);
|
||||||
void (*DumpHandles)(void (*dumpfn)(const char *fmt, ...));
|
|
||||||
void (*RegisterProfiler)(IProfilingTool *tool);
|
void (*RegisterProfiler)(IProfilingTool *tool);
|
||||||
void (*OnRootCommand)(const ICommandArgs *args);
|
void (*OnRootCommand)(const ICommandArgs *args);
|
||||||
IDataPack * (*CreateDataPack)();
|
IDataPack * (*CreateDataPack)();
|
||||||
|
@ -1066,11 +1066,23 @@ bool HandleSystem::TryAndFreeSomeHandles()
|
|||||||
return scripts->UnloadPlugin(highest_owner);
|
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;
|
unsigned int total_size = 0;
|
||||||
rep("%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
|
rep(fn, "%-10.10s\t%-20.20s\t%-20.20s\t%-10.10s", "Handle", "Owner", "Type", "Memory");
|
||||||
rep("--------------------------------------------------------------------------");
|
rep(fn, "--------------------------------------------------------------------------");
|
||||||
for (unsigned int i = 1; i <= m_HandleTail; i++)
|
for (unsigned int i = 1; i <= m_HandleTail; i++)
|
||||||
{
|
{
|
||||||
if (m_Handles[i].set != HandleSet_Used)
|
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
|
if (pType->dispatch->GetDispatchVersion() < HANDLESYS_MEMUSAGE_MIN_VERSION
|
||||||
|| !bresult)
|
|| !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
|
else
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
ke::SafeSprintf(buffer, sizeof(buffer), "%d", size);
|
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;
|
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 <IHandleSys.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sm_namehashset.h>
|
#include <sm_namehashset.h>
|
||||||
#include <am-string.h>
|
#include <amtl/am-string.h>
|
||||||
|
#include <amtl/am-function.h>
|
||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
|
|
||||||
#define HANDLESYS_MAX_HANDLES (1<<15)
|
#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 :
|
class HandleSystem :
|
||||||
public IHandleSys
|
public IHandleSys
|
||||||
@ -163,7 +164,7 @@ public: //IHandleSystem
|
|||||||
const HandleAccess *pAccess,
|
const HandleAccess *pAccess,
|
||||||
HandleError *err);
|
HandleError *err);
|
||||||
|
|
||||||
void Dump(HANDLE_REPORTER rep);
|
void Dump(const HandleReporter &reporter);
|
||||||
|
|
||||||
/* Bypasses security checks. */
|
/* Bypasses security checks. */
|
||||||
Handle_t FastCloneHandle(Handle_t hndl);
|
Handle_t FastCloneHandle(Handle_t hndl);
|
||||||
|
@ -27,10 +27,15 @@
|
|||||||
#include "RootConsoleMenu.h"
|
#include "RootConsoleMenu.h"
|
||||||
#include <amtl/am-string.h>
|
#include <amtl/am-string.h>
|
||||||
#include <sourcemod_version.h>
|
#include <sourcemod_version.h>
|
||||||
|
#include <ISourceMod.h>
|
||||||
#include <bridge/include/CoreProvider.h>
|
#include <bridge/include/CoreProvider.h>
|
||||||
|
#include "HandleSys.h"
|
||||||
|
|
||||||
RootConsoleMenu g_RootMenu;
|
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()
|
RootConsoleMenu::RootConsoleMenu()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -49,6 +54,9 @@ void RootConsoleMenu::OnSourceModStartup(bool late)
|
|||||||
{
|
{
|
||||||
AddRootConsoleCommand3("version", "Display version information", this);
|
AddRootConsoleCommand3("version", "Display version information", this);
|
||||||
AddRootConsoleCommand3("credits", "Display credits listing", 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()
|
void RootConsoleMenu::OnSourceModAllInitialized()
|
||||||
@ -232,3 +240,45 @@ void RootConsoleMenu::OnRootConsoleCommand(const char *cmdname, const ICommandAr
|
|||||||
ConsolePrint(" http://www.sourcemod.net/");
|
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);
|
g_CoreNatives.AddNatives(natives);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpHandles(void (*dumpfn)(const char *fmt, ...))
|
|
||||||
{
|
|
||||||
g_HandleSys.Dump(dumpfn);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RegisterProfiler(IProfilingTool *tool)
|
static void RegisterProfiler(IProfilingTool *tool)
|
||||||
{
|
{
|
||||||
g_ProfileToolManager.RegisterTool(tool);
|
g_ProfileToolManager.RegisterTool(tool);
|
||||||
@ -154,7 +149,6 @@ static sm_logic_t logic =
|
|||||||
&g_DbgReporter,
|
&g_DbgReporter,
|
||||||
GenerateError,
|
GenerateError,
|
||||||
AddNatives,
|
AddNatives,
|
||||||
DumpHandles,
|
|
||||||
RegisterProfiler,
|
RegisterProfiler,
|
||||||
OnRootCommand,
|
OnRootCommand,
|
||||||
CDataPack::New,
|
CDataPack::New,
|
||||||
|
@ -70,67 +70,3 @@ CON_COMMAND(sm, "SourceMod Menu")
|
|||||||
|
|
||||||
logicore.OnRootCommand(&cargs);
|
logicore.OnRootCommand(&cargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *g_pHndlLog = NULL;
|
|
||||||
|
|
||||||
void write_handles_to_log(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vfprintf(g_pHndlLog, fmt, ap);
|
|
||||||
fprintf(g_pHndlLog, "\n");
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
void write_handles_to_game(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
va_list ap;
|
|
||||||
char buffer[1024];
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = ke::SafeSprintf(buffer, sizeof(buffer)-2, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
buffer[len] = '\n';
|
|
||||||
buffer[len+1] = '\0';
|
|
||||||
|
|
||||||
engine->LogPrint(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
CON_COMMAND(sm_dump_handles, "Dumps Handle usage to a file for finding Handle leaks")
|
|
||||||
{
|
|
||||||
#if SOURCE_ENGINE <= SE_DARKMESSIAH
|
|
||||||
CCommand args;
|
|
||||||
#endif
|
|
||||||
if (args.ArgC() < 2)
|
|
||||||
{
|
|
||||||
UTIL_ConsolePrint("Usage: sm_dump_handles <file> or <log> for game logs");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(args.Arg(1), "log") != 0)
|
|
||||||
{
|
|
||||||
char filename[PLATFORM_MAX_PATH];
|
|
||||||
const char *arg = args.Arg(1);
|
|
||||||
g_SourceMod.BuildPath(Path_Game, filename, sizeof(filename), "%s", arg);
|
|
||||||
|
|
||||||
FILE *fp = fopen(filename, "wt");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
UTIL_ConsolePrint("Failed to open \"%s\" for writing", filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_pHndlLog = fp;
|
|
||||||
logicore.DumpHandles(write_handles_to_log);
|
|
||||||
g_pHndlLog = NULL;
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logicore.DumpHandles(write_handles_to_game);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit c4c2aa3e97157407c3832b40fed43ba9cd24a2c1
|
Subproject commit 298217cbbfac16851bb58574bc6744f58b260b15
|
Loading…
Reference in New Issue
Block a user