Author: weiden Date: Sat Oct 27 08:00:25 2007 New Revision: 29910
URL: http://svn.reactos.org/svn/reactos?rev=29910&view=rev Log: Display a list of all leaked memory blocks when terminating
Modified: trunk/reactos/base/shell/cmd/cmddbg.c
Modified: trunk/reactos/base/shell/cmd/cmddbg.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmddbg.c?rev... ============================================================================== --- trunk/reactos/base/shell/cmd/cmddbg.c (original) +++ trunk/reactos/base/shell/cmd/cmddbg.c Sat Oct 27 08:00:25 2007 @@ -9,17 +9,25 @@ typedef struct { size_t size; + LIST_ENTRY list_entry; const char *file; int line; } alloc_info, *palloc_info;
static size_t allocations = 0; static size_t allocated_memory = 0; +static LIST_ENTRY alloc_list_head = {&alloc_list_head, &alloc_list_head};
static void * get_base_ptr(void *ptr) { return (void *)((UINT_PTR)ptr - REDZONE_SIZE - sizeof(alloc_info)); +} + +static void * +get_ptr_from_base(palloc_info info) +{ + return (void*)((size_t)(info + 1) + REDZONE_SIZE); }
static void * @@ -88,6 +96,50 @@ return sizeof(alloc_info) + size + (2 * REDZONE_SIZE); }
+static void +add_mem_to_list(void *ptr) +{ + palloc_info info = (palloc_info)ptr; + InsertTailList(&alloc_list_head, &info->list_entry); +} + +static void +del_mem_from_list(void *ptr) +{ + palloc_info info = (palloc_info)ptr; + RemoveEntryList(&info->list_entry); +} + +static void +dump_mem_list(void) +{ + palloc_info info; + PLIST_ENTRY entry; + void *ptr; + + entry = alloc_list_head.Flink; + while (entry != &alloc_list_head) + { + info = CONTAINING_RECORD(entry, alloc_info, list_entry); + + DbgPrint(" * Block: 0x%p Size: %lu allocated from %s:%d\n", get_ptr_from_base(info), info->size, info->file, info->line); + + ptr = (void *)(info + 1); + if (!check_redzone_region(ptr, REDZONE_LEFT, &ptr)) + { + DbgPrint(" !!! Detected buffer underflow !!!\n"); + } + + ptr = (void *)((UINT_PTR)ptr + info->size); + if (!check_redzone_region(ptr, REDZONE_RIGHT, NULL)) + { + DbgPrint(" !!! Detected buffer overflow !!!\n"); + } + + entry = entry->Flink; + } +} + void * cmd_alloc_dbg(size_t size, const char *file, int line) { @@ -98,6 +150,7 @@ { allocations++; allocated_memory += size; + add_mem_to_list(newptr); newptr = write_redzone(newptr, size, file, line); }
@@ -122,12 +175,16 @@ prev_size = ((palloc_info)ptr)->size; check_redzone(ptr, file, line);
+ del_mem_from_list(ptr); newptr = realloc(ptr, calculate_size_with_redzone(size)); if (newptr != NULL) { allocated_memory += size - prev_size; + add_mem_to_list(newptr); newptr = write_redzone(newptr, size, file, line); } + else + add_mem_to_list(ptr);
return newptr; } @@ -141,6 +198,7 @@ check_redzone(ptr, file, line); allocations--; allocated_memory -= ((palloc_info)ptr)->size; + del_mem_from_list(ptr); }
free(ptr); @@ -179,6 +237,8 @@ if (allocations != 0 || allocated_memory != 0) { DbgPrint("CMD: Leaking %lu bytes of memory in %lu blocks! Exit code: %d\n", allocated_memory, allocations, code); + if (allocations != 0) + dump_mem_list(); }
ExitProcess(code);