nicer memory leak diagnostics

This commit is contained in:
aap 2020-04-24 22:58:35 +02:00
parent 0ddce08c94
commit 7fdb483d4e
2 changed files with 38 additions and 19 deletions

View File

@ -34,6 +34,8 @@ Engine::State Engine::state = Dead;
MemoryFunctions Engine::memfuncs; MemoryFunctions Engine::memfuncs;
PluginList Driver::s_plglist[NUM_PLATFORMS]; 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 *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); } void *realloc_h(void *p, size_t sz, uint32 hint) { return realloc(p, sz); }
@ -42,6 +44,7 @@ struct MemoryBlock
size_t sz; size_t sz;
uint32 hint; uint32 hint;
void *origPtr; void *origPtr;
const char *codeline;
LLLink inAllocList; LLLink inAllocList;
}; };
LinkList allocations; LinkList allocations;
@ -70,6 +73,7 @@ malloc_managed(size_t sz, uint32 hint)
mem->sz = sz; mem->sz = sz;
mem->hint = hint; mem->hint = hint;
mem->origPtr = origPtr; mem->origPtr = origPtr;
mem->codeline = allocLocation;
allocations.add(&mem->inAllocList); allocations.add(&mem->inAllocList);
return data; return data;
@ -101,6 +105,7 @@ realloc_managed(void *p, size_t sz, uint32 hint)
mem->sz = sz; mem->sz = sz;
mem->hint = hint; mem->hint = hint;
mem->origPtr = origPtr; mem->origPtr = origPtr;
mem->codeline = allocLocation;
allocations.add(&mem->inAllocList); allocations.add(&mem->inAllocList);
totalMemoryAllocated += mem->sz; totalMemoryAllocated += mem->sz;
@ -141,6 +146,8 @@ void *mustrealloc_h(void *p, size_t sz, uint32 hint)
return nil; return nil;
} }
//#define TRACK_ALLOCATIONS
// This function mainly registers engine plugins // This function mainly registers engine plugins
bool32 bool32
Engine::init(void) Engine::init(void)
@ -154,15 +161,15 @@ Engine::init(void)
allocations.init(); allocations.init();
// TODO: make this an argument // TODO: make this an argument
/**/ #ifdef TRACK_ALLOCATIONS
memfuncs.rwmalloc = malloc_h;
memfuncs.rwrealloc = realloc_h;
memfuncs.rwfree = free;
/*/
memfuncs.rwmalloc = malloc_managed; memfuncs.rwmalloc = malloc_managed;
memfuncs.rwrealloc = realloc_managed; memfuncs.rwrealloc = realloc_managed;
memfuncs.rwfree = free_managed; memfuncs.rwfree = free_managed;
/*/ #else
memfuncs.rwmalloc = malloc_h;
memfuncs.rwrealloc = realloc_h;
memfuncs.rwfree = free;
#endif
memfuncs.rwmustmalloc = mustmalloc_h; memfuncs.rwmustmalloc = mustmalloc_h;
memfuncs.rwmustrealloc = mustrealloc_h; memfuncs.rwmustrealloc = mustrealloc_h;
@ -287,10 +294,12 @@ Engine::term(void)
return; return;
} }
// FORLIST(lnk, allocations){ #ifdef TRACK_ALLOCATIONS
// MemoryBlock *mem = LLLinkGetData(lnk, MemoryBlock, inAllocList); FORLIST(lnk, allocations){
// printf("sz %d hint %X\n", mem->sz, mem->hint); MemoryBlock *mem = LLLinkGetData(lnk, MemoryBlock, inAllocList);
// } printf("sz %d hint %X\n %s\n", mem->sz, mem->hint, mem->codeline);
}
#endif
Engine::state = Dead; Engine::state = Dead;
} }

View File

@ -185,16 +185,26 @@ struct Engine
extern Engine *engine; extern Engine *engine;
// These must be macros because we might want to pass __FILE__ and __LINE__ later #define RWTOSTR_(X) #X
#define rwMalloc(s, h) rw::Engine::memfuncs.rwmalloc(s,h) #define RWTOSTR(X) RWTOSTR_(X)
#define rwMallocT(t, s, h) (t*)rw::Engine::memfuncs.rwmalloc((s)*sizeof(t),h) #define RWHERE "file: " __FILE__ " line: " RWTOSTR(__LINE__)
#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) 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 rwFree(p) rw::Engine::memfuncs.rwfree(p)
#define rwNew(s, h) rw::Engine::memfuncs.rwmustmalloc(s,h) #define rwNew(s, h) rw::mustmalloc_LOC(s,h,RWHERE)
#define rwNewT(t, s, h) (t*)rw::Engine::memfuncs.rwmustmalloc((s)*sizeof(t),h) #define rwNewT(t, s, h) (t*)rw::mustmalloc_LOC((s)*sizeof(t),h,RWHERE)
#define rwResize(p, s, h) rw::Engine::memfuncs.rwmustrealloc(p,s,h) #define rwResize(p, s, h) rw::mustrealloc_LOC(p,s,h,RWHERE)
#define rwResizeT(t, p, s, h) (t*)rw::Engine::memfuncs.rwmustrealloc(p,(s)*sizeof(t),h) #define rwResizeT(t, p, s, h) (t*)rw::mustrealloc_LOC(p,(s)*sizeof(t),h,RWHERE)
namespace null { namespace null {
void beginUpdate(Camera*); void beginUpdate(Camera*);