Created
April 13, 2013 16:47
-
-
Save crimsonwoods/5379148 to your computer and use it in GitHub Desktop.
a patch to add memory leak detection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git src/state.c src/state.c | |
index 0b6c755..528143e 100644 | |
--- src/state.c | |
+++ src/state.c | |
@@ -55,17 +55,124 @@ filename(char const *path) | |
} | |
return path; | |
} | |
+ | |
+typedef struct alloc_header_t { | |
+ uint32_t guard; | |
+ size_t size; | |
+ char const *file; | |
+ int line; | |
+ char const *func; | |
+} alloc_header_t; | |
+ | |
+#if defined(MRB_MEMLEAK_DETECTION) | |
+typedef struct ptr_list_t { | |
+ void *ptr; | |
+ struct ptr_list_t *next; | |
+} ptr_list_t; | |
+typedef struct ptr_tree_t { | |
+ ptr_list_t *lists[256][256]; | |
+}ptr_tree_t; | |
+ | |
+static ptr_tree_t ptr_tree; | |
+static int volatile ptr_tree_initialized = 0; | |
+ | |
+static void | |
+register_ptr(void *ptr) { | |
+ intptr_t ip = (intptr_t)ptr; | |
+ if (!ptr_tree_initialized) { | |
+ memset(&ptr_tree, 0, sizeof(ptr_tree)); | |
+ ptr_tree_initialized = 1; | |
+ } | |
+ ptr_list_t *l = ptr_tree.lists[(ip >> 8) & 0xff][(ip >> 16) & 0xff]; | |
+ | |
+ ptr_list_t *new_l = (ptr_list_t*)malloc(sizeof(ptr_list_t)); | |
+ new_l->ptr = ptr; | |
+ new_l->next = NULL; | |
+ | |
+ if (NULL == l) { | |
+ ptr_tree.lists[(ip >> 8) & 0xff][(ip >> 16) & 0xff] = new_l; | |
+ } else { | |
+ while (NULL != l->next) { | |
+ l = l->next; | |
+ } | |
+ l->next = new_l; | |
+ } | |
+} | |
+static void | |
+unregister_ptr(void *ptr) { | |
+ intptr_t ip = (intptr_t)ptr; | |
+ ptr_list_t *l = ptr_tree.lists[(ip >> 8) & 0xff][(ip >> 16) & 0xff]; | |
+ ptr_list_t *p = l; | |
+ if (NULL != l) { | |
+ do { | |
+ if (ptr == l->ptr) { | |
+ if (p == l) { | |
+ ptr_tree.lists[(ip >> 8) & 0xff][(ip >> 16) & 0xff] = l->next; | |
+ } else { | |
+ p->next = l->next; | |
+ } | |
+ free(l); | |
+ break; | |
+ } | |
+ p = l; | |
+ l = l->next; | |
+ } while (NULL != l); | |
+ } | |
+} | |
+static void __attribute__((destructor)) | |
+release_ptr_tree() | |
+{ | |
+ int i,j; | |
+ for (i = 0; i < 256; ++i) { | |
+ for (j = 0; j < 256; ++j) { | |
+ ptr_list_t *l = ptr_tree.lists[i][j]; | |
+ if (!l) { | |
+ continue; | |
+ } | |
+ do { | |
+ alloc_header_t const * const hdr = (alloc_header_t*)l->ptr; | |
+ void *ptr = (uint8_t *)l->ptr + sizeof(alloc_header_t); | |
+ fprintf(stderr, "LEAK : %10p %8lu %15s %4d (%s)\n", ptr, hdr->size, filename(hdr->file), hdr->line, hdr->func); | |
+ l = l->next; | |
+ } while (NULL != l); | |
+ } | |
+ } | |
+} | |
+#else | |
+#define register_ptr(ptr) | |
+#define unregister_ptr(ptr) | |
+#endif | |
+ | |
static void* | |
allocf(mrb_state *mrb, void *p, size_t size, void *ud, char const *file, int line, char const *func) | |
{ | |
if (size == 0) { | |
- fprintf(stderr, "FREE : %10p %15s %4d (%s)\n", p, filename(file), line, func); | |
- free(p); | |
+ if (NULL != p) { | |
+ alloc_header_t *hdr = (alloc_header_t *)((uint8_t *)p - sizeof(alloc_header_t)); | |
+ if (hdr->guard != 0xdeadbeef) { | |
+ fprintf(stderr, "#### DETECT HEAP MEMORY CORRUPTION!!!! ####\n"); | |
+ } | |
+ fprintf(stderr, "FREE : %10p %8lu %15s %4d (%s)\n", hdr + 1, hdr->size, filename(file), line, func); | |
+ free(hdr); | |
+ unregister_ptr(hdr); | |
+ } | |
return NULL; | |
} | |
else { | |
- void *new_ptr = realloc(p, size); | |
+ alloc_header_t *hdr = (NULL == p) ? NULL : (alloc_header_t*)((uint8_t *)p - sizeof(alloc_header_t)); | |
+ void *new_ptr = realloc(hdr, sizeof(alloc_header_t) + size); | |
if (new_ptr) { | |
+ alloc_header_t *new_hdr = (alloc_header_t *)new_ptr; | |
+ if (new_hdr != hdr) { | |
+ unregister_ptr(hdr); | |
+ register_ptr(new_hdr); | |
+ new_hdr->guard = 0xdeadbeef; | |
+ new_hdr->file = file; | |
+ new_hdr->line = line; | |
+ new_hdr->func = func; | |
+ } | |
+ new_hdr->size = size; | |
+ new_ptr = (void*)((uint8_t *)new_ptr) + sizeof(alloc_header_t); | |
if (NULL == p) { | |
fprintf(stderr, "ALLOCATE: %10p %8lu %15s %4d (%s)\n", new_ptr, size, filename(file), line, func); | |
} else { |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment