summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-Trunk.txt6
-rw-r--r--src/common/malloc.c66
-rw-r--r--src/common/malloc.h12
3 files changed, 48 insertions, 36 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 82a7c6a12..14445a960 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -1,5 +1,11 @@
Date Added
+2011/07/20
+ * Made GCOLLECT use it's debug functions. [FlavioJS]
+ * 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.
2011/07/19
* Made NO_MEMMGR only be set as a default value, allowing for simultaneous use with the memory libraries. [FlavioJS]
* Moved memory library selection to malloc.c to avoid poisoning the namespace of the rest of the code.
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);