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?re…
==============================================================================
--- 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);