From 7fdb483d4e0d694be3d151764f19b9832719edd7 Mon Sep 17 00:00:00 2001 From: aap Date: Fri, 24 Apr 2020 22:58:35 +0200 Subject: [PATCH] nicer memory leak diagnostics --- src/engine.cpp | 29 +++++++++++++++++++---------- src/rwengine.h | 28 +++++++++++++++++++--------- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index d8bbb3f..5cd0e78 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -34,6 +34,8 @@ Engine::State Engine::state = Dead; MemoryFunctions Engine::memfuncs; PluginList Driver::s_plglist[NUM_PLATFORMS]; +const char *allocLocation; + void *malloc_h(size_t sz, uint32 hint) { if(sz == 0) return nil; return malloc(sz); } void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); } @@ -42,6 +44,7 @@ struct MemoryBlock size_t sz; uint32 hint; void *origPtr; + const char *codeline; LLLink inAllocList; }; LinkList allocations; @@ -70,6 +73,7 @@ malloc_managed(size_t sz, uint32 hint) mem->sz = sz; mem->hint = hint; mem->origPtr = origPtr; + mem->codeline = allocLocation; allocations.add(&mem->inAllocList); return data; @@ -101,6 +105,7 @@ realloc_managed(void *p, size_t sz, uint32 hint) mem->sz = sz; mem->hint = hint; mem->origPtr = origPtr; + mem->codeline = allocLocation; allocations.add(&mem->inAllocList); totalMemoryAllocated += mem->sz; @@ -141,6 +146,8 @@ void *mustrealloc_h(void *p, size_t sz, uint32 hint) return nil; } +//#define TRACK_ALLOCATIONS + // This function mainly registers engine plugins bool32 Engine::init(void) @@ -154,15 +161,15 @@ Engine::init(void) allocations.init(); // TODO: make this an argument -/**/ - memfuncs.rwmalloc = malloc_h; - memfuncs.rwrealloc = realloc_h; - memfuncs.rwfree = free; -/*/ +#ifdef TRACK_ALLOCATIONS memfuncs.rwmalloc = malloc_managed; memfuncs.rwrealloc = realloc_managed; memfuncs.rwfree = free_managed; -/*/ +#else + memfuncs.rwmalloc = malloc_h; + memfuncs.rwrealloc = realloc_h; + memfuncs.rwfree = free; +#endif memfuncs.rwmustmalloc = mustmalloc_h; memfuncs.rwmustrealloc = mustrealloc_h; @@ -287,10 +294,12 @@ Engine::term(void) return; } -// FORLIST(lnk, allocations){ -// MemoryBlock *mem = LLLinkGetData(lnk, MemoryBlock, inAllocList); -// printf("sz %d hint %X\n", mem->sz, mem->hint); -// } +#ifdef TRACK_ALLOCATIONS + FORLIST(lnk, allocations){ + MemoryBlock *mem = LLLinkGetData(lnk, MemoryBlock, inAllocList); + printf("sz %d hint %X\n %s\n", mem->sz, mem->hint, mem->codeline); + } +#endif Engine::state = Dead; } diff --git a/src/rwengine.h b/src/rwengine.h index 14f1321..a32db04 100644 --- a/src/rwengine.h +++ b/src/rwengine.h @@ -185,16 +185,26 @@ struct Engine extern Engine *engine; -// These must be macros because we might want to pass __FILE__ and __LINE__ later -#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h) -#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h) -#define rwRealloc(p, s, h) rw::Engine::memfuncs.rwrealloc(p,s,h) -#define rwReallocT(t, p, s, h) (t*)rw::Engine::memfuncs.rwrealloc(p,(s)*sizeof(t),h) +#define RWTOSTR_(X) #X +#define RWTOSTR(X) RWTOSTR_(X) +#define RWHERE "file: " __FILE__ " line: " RWTOSTR(__LINE__) + +extern const char *allocLocation; + +inline void *malloc_LOC(size_t sz, uint32 hint, const char *here) { allocLocation = here; return rw::Engine::memfuncs.rwmalloc(sz,hint); } +inline void *realloc_LOC(void *p, size_t sz, uint32 hint, const char *here) { allocLocation = here; return rw::Engine::memfuncs.rwrealloc(p,sz,hint); } +inline void *mustmalloc_LOC(size_t sz, uint32 hint, const char *here) { allocLocation = here; return rw::Engine::memfuncs.rwmustmalloc(sz,hint); } +inline void *mustrealloc_LOC(void *p, size_t sz, uint32 hint, const char *here) { allocLocation = here; return rw::Engine::memfuncs.rwmustrealloc(p,sz,hint); } + +#define rwMalloc(s, h) rw::malloc_LOC(s,h,RWHERE) +#define rwMallocT(t, s, h) (t*)rw::malloc_LOC((s)*sizeof(t),h,RWHERE) +#define rwRealloc(p, s, h) rw::realloc_LOC(p,s,h,RWHERE) +#define rwReallocT(t, p, s, h) (t*)rw::realloc_LOC(p,(s)*sizeof(t),h,RWHERE) #define rwFree(p) rw::Engine::memfuncs.rwfree(p) -#define rwNew(s, h) rw::Engine::memfuncs.rwmustmalloc(s,h) -#define rwNewT(t, s, h) (t*)rw::Engine::memfuncs.rwmustmalloc((s)*sizeof(t),h) -#define rwResize(p, s, h) rw::Engine::memfuncs.rwmustrealloc(p,s,h) -#define rwResizeT(t, p, s, h) (t*)rw::Engine::memfuncs.rwmustrealloc(p,(s)*sizeof(t),h) +#define rwNew(s, h) rw::mustmalloc_LOC(s,h,RWHERE) +#define rwNewT(t, s, h) (t*)rw::mustmalloc_LOC((s)*sizeof(t),h,RWHERE) +#define rwResize(p, s, h) rw::mustrealloc_LOC(p,s,h,RWHERE) +#define rwResizeT(t, p, s, h) (t*)rw::mustrealloc_LOC(p,(s)*sizeof(t),h,RWHERE) namespace null { void beginUpdate(Camera*);