Initial commit — leak-hunt project complete
Five bugs identified and patched in retail Asheron's Call client: - v3b: palette refcount over-increment (3-byte NOP at two sites) - v5: RenderSurface PurgeResource no-op stub (vtable slot 2 thunk) - v11: two dangling-pointer crash guards (NULL-check + reorder) - v14: CEnvCell::Destroy ClipPlaneList leak (18-byte JMP to cleanup thunk) - v22: unpacker stale-pointer SEH guard (whole-function __try/__except) All five ship in leakfix.dll (117 KB, SHA d282f23c…) which is loaded by acclient.exe at process start via PE import table patching by tools/install_leakfix.py. Controlled 15-client fleet soak: unpatched control died at 26h with palette exhaustion; all 14 patched clients survived past that point and reached ≥5-day uptime. Residual ~15 MB/h growth traced to d3d9.dll's internal slab allocator (260KB surface backing buffers retained after Release). See REPORT.md §10 for the full investigation; conclusion is that it's unfixable from outside d3d9. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
57b5e43d0e
199 changed files with 1648333 additions and 0 deletions
74
dll/leakfix/stable/src.iter3/logging.cpp
Normal file
74
dll/leakfix/stable/src.iter3/logging.cpp
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
#include "logging.h"
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
|
||||
namespace {
|
||||
HANDLE g_log = INVALID_HANDLE_VALUE;
|
||||
CRITICAL_SECTION g_cs;
|
||||
bool g_cs_inited = false;
|
||||
|
||||
void ensure_cs() {
|
||||
if (!g_cs_inited) {
|
||||
InitializeCriticalSection(&g_cs);
|
||||
g_cs_inited = true;
|
||||
}
|
||||
}
|
||||
|
||||
void write_line(const char* s, size_t len) {
|
||||
if (g_log == INVALID_HANDLE_VALUE) return;
|
||||
DWORD written = 0;
|
||||
WriteFile(g_log, s, (DWORD)len, &written, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
namespace leakfix {
|
||||
|
||||
void log_init(const char* path) {
|
||||
ensure_cs();
|
||||
EnterCriticalSection(&g_cs);
|
||||
if (g_log != INVALID_HANDLE_VALUE) { LeaveCriticalSection(&g_cs); return; }
|
||||
g_log = CreateFileA(path, FILE_APPEND_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
SetFilePointer(g_log, 0, nullptr, FILE_END);
|
||||
LeaveCriticalSection(&g_cs);
|
||||
logf("===== leakfix.dll loaded (pid=%lu) =====", GetCurrentProcessId());
|
||||
}
|
||||
|
||||
void log_close() {
|
||||
ensure_cs();
|
||||
EnterCriticalSection(&g_cs);
|
||||
if (g_log != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(g_log);
|
||||
g_log = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
LeaveCriticalSection(&g_cs);
|
||||
}
|
||||
|
||||
void logf(const char* fmt, ...) {
|
||||
ensure_cs();
|
||||
char buf[1024];
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
int n = std::snprintf(buf, sizeof(buf),
|
||||
"[%04d-%02d-%02d %02d:%02d:%02d.%03d] ",
|
||||
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
va_list ap; va_start(ap, fmt);
|
||||
int m = std::vsnprintf(buf + n, sizeof(buf) - n - 2, fmt, ap);
|
||||
va_end(ap);
|
||||
if (m < 0) m = 0;
|
||||
int total = n + m;
|
||||
if (total >= (int)sizeof(buf) - 1) total = sizeof(buf) - 2;
|
||||
buf[total] = '\n';
|
||||
buf[total + 1] = '\0';
|
||||
|
||||
EnterCriticalSection(&g_cs);
|
||||
write_line(buf, (size_t)total + 1);
|
||||
LeaveCriticalSection(&g_cs);
|
||||
|
||||
// Also forward to debugger if attached
|
||||
OutputDebugStringA(buf);
|
||||
}
|
||||
|
||||
} // namespace leakfix
|
||||
Loading…
Add table
Add a link
Reference in a new issue