From 427ebfd9e94a68ca15ca6b51378b80871dde95b9 Mon Sep 17 00:00:00 2001 From: flaviojs Date: Wed, 20 Jul 2011 22:23:13 +0000 Subject: * Made GCOLLECT use it's debug functions. * Turned off garbage collection for GCOLLECT since there's nothing to do with explicit frees. * Added malloc_verify_ptr/malloc_usage code for all memory libraries. * Added malloc_memory_check for debug purposes, tests memory for errors and memory leaks. * Added explicit memory check on malloc_final. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14917 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/common/malloc.c | 66 +++++++++++++++++++++++++++++++---------------------- src/common/malloc.h | 12 +++------- 2 files changed, 42 insertions(+), 36 deletions(-) (limited to 'src/common') diff --git a/src/common/malloc.c b/src/common/malloc.c index 32367792f..1769e0982 100644 --- a/src/common/malloc.c +++ b/src/common/malloc.c @@ -21,6 +21,9 @@ # define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) # define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) # define FREE(p,file,line,func) mwFree((p),(file),(line)) +# define MEMORY_USAGE() 0 +# define MEMORY_VERIFY(ptr) mwIsSafeAddr(ptr, 1) +# define MEMORY_CHECK() CHECK() #elif defined(DMALLOC) @@ -32,17 +35,26 @@ # define REALLOC(p,n,file,line,func) dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0) # define STRDUP(p,file,line,func) strdup(p) # define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() dmalloc_memory_allocated() +# define MEMORY_VERIFY(ptr) (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR) +# define MEMORY_CHECK() dmalloc_log_stats(); dmalloc_log_unfreed() #elif defined(GCOLLECT) # include "gc.h" -# define MALLOC(n,file,line,func) GC_MALLOC(n) -# define CALLOC(m,n,file,line,func) GC_MALLOC((m)*(n)) -# define REALLOC(p,n,file,line,func) GC_REALLOC((p),(n)) -# define STRDUP(p,file,line,func) _bstrdup(p) -# define FREE(p,file,line,func) GC_FREE(p) - - char * _bstrdup(const char *); +# ifdef GC_ADD_CALLER +# define RETURN_ADDR 0, +# else +# define RETURN_ADDR +# endif +# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) +# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) +# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) +# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) +# define FREE(p,file,line,func) GC_debug_free(p) +# define MEMORY_USAGE() GC_get_heap_size() +# define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) +# define MEMORY_CHECK() GC_gcollect() #else @@ -51,6 +63,9 @@ # define REALLOC(p,n,file,line,func) realloc((p),(n)) # define STRDUP(p,file,line,func) strdup(p) # define FREE(p,file,line,func) free(p) +# define MEMORY_USAGE() 0 +# define MEMORY_VERIFY(ptr) true +# define MEMORY_CHECK() #endif @@ -104,17 +119,6 @@ void aFree_(void *p, const char *file, int line, const char *func) p = NULL; } -#ifdef GCOLLECT - -char* _bstrdup(const char *chr) -{ - int len = strlen(chr); - char *ret = (char*)GC_MALLOC(len + 1); - if (ret) memcpy(ret, chr, len + 1); - return ret; -} - -#endif #ifdef USE_MEMMGR @@ -660,23 +664,32 @@ static void memmgr_init (void) *-------------------------------------- */ + +/// Tests the memory for errors and memory leaks. +void malloc_memory_check(void) +{ + MEMORY_CHECK(); +} + + +/// Returns true if a pointer is valid. +/// The check is best-effort, false positives are possible. bool malloc_verify_ptr(void* ptr) { #ifdef USE_MEMMGR - return memmgr_verify(ptr); -#elif defined(DMALLOC) - return (dmalloc_verify(ptr) == DMALLOC_VERIFY_NOERROR); + return memmgr_verify(ptr) && MEMORY_VERIFY(ptr); #else - return true; + return MEMORY_VERIFY(ptr); #endif } + size_t malloc_usage (void) { #ifdef USE_MEMMGR return memmgr_usage (); #else - return 0; + return MEMORY_USAGE(); #endif } @@ -685,10 +698,7 @@ void malloc_final (void) #ifdef USE_MEMMGR memmgr_final (); #endif -#ifdef GCOLLECT - GC_find_leak = 1; - GC_gcollect(); -#endif + MEMORY_CHECK(); } void malloc_init (void) @@ -698,6 +708,8 @@ void malloc_init (void) dmalloc_debug_setup(getenv("DMALLOC_OPTIONS")); #endif #ifdef GCOLLECT + // don't garbage collect, only report inaccessible memory that was not deallocated + GC_find_leak = 1; GC_INIT(); #endif #ifdef USE_MEMMGR diff --git a/src/common/malloc.h b/src/common/malloc.h index e565b4eb0..5f8191d92 100644 --- a/src/common/malloc.h +++ b/src/common/malloc.h @@ -6,20 +6,13 @@ #include "../common/cbasetypes.h" -// Q: What are the 'a'-variant allocation functions? -// A: They allocate memory from the stack, which is automatically -// freed when the invoking function returns. -// But it's not portable (http://c-faq.com/malloc/alloca.html) -// and I have doubts our implementation works. -// -> They should NOT be used, period. - #define ALC_MARK __FILE__, __LINE__, __func__ -// default memory manager +// default use of the built-in memory manager #if !defined(NO_MEMMGR) && !defined(USE_MEMMGR) #if defined(MEMWATCH) || defined(DMALLOC) || defined(GCOLLECT) -// disable built-in memory manager when using another manager +// disable built-in memory manager when using another memory library #define NO_MEMMGR #else // use built-in memory manager by default @@ -95,6 +88,7 @@ //////////////////////////////////////////////// +void malloc_memory_check(void); bool malloc_verify_ptr(void* ptr); size_t malloc_usage (void); void malloc_init (void); -- cgit v1.2.3-60-g2f50