summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2008-07-11 23:33:59 -0400
committerRay Strode <rstrode@redhat.com>2008-07-12 12:04:35 -0400
commit1296be2fc72c3439a00c39b2f5eea35ce0ac0113 (patch)
treeeaef6dcf1b8fe2afbe1d652d934176141131434e
parent458c6ead8572f8cea248844b6860156a00f3f45b (diff)
downloaddbus-1296be2fc72c3439a00c39b2f5eea35ce0ac0113.tar.gz
Add some sloppy code for locating memory leaks
It would need quite a bit of polish before it could ever be merged to master.
-rw-r--r--dbus/dbus-memory.c119
1 files changed, 115 insertions, 4 deletions
diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c
index 8dc91471..23157e65 100644
--- a/dbus/dbus-memory.c
+++ b/dbus/dbus-memory.c
@@ -26,6 +26,8 @@
#include "dbus-sysdeps.h"
#include "dbus-list.h"
#include <stdlib.h>
+#include <execinfo.h>
+#include <stdio.h>
/**
* @defgroup DBusMemory Memory Allocation
@@ -107,6 +109,16 @@ static dbus_bool_t disable_mem_pools = FALSE;
static dbus_bool_t backtrace_on_fail_alloc = FALSE;
static DBusAtomic n_blocks_outstanding = {0};
+__attribute__((packed))
+struct block
+{
+ void *symbols[500];
+ long number_of_symbols;
+ long size;
+ char memory[0];
+};
+static struct block *blocks[16384];
+
/** value stored in guard padding for debugging buffer overrun */
#define GUARD_VALUE 0xdeadbeef
/** size of the information about the block stored in guard mode */
@@ -467,12 +479,27 @@ dbus_malloc (size_t bytes)
#endif
else
{
+ struct block *block;
+ int i;
void *mem;
- mem = malloc (bytes);
+ block = malloc (sizeof (struct block) + bytes + 256);
+ block->size = bytes;
+ block->number_of_symbols = backtrace (block->symbols, 100);
+ mem = &block->memory;
+
#ifdef DBUS_BUILD_TESTS
if (mem)
_dbus_atomic_inc (&n_blocks_outstanding);
#endif
+ for (i = 0; i < sizeof (blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] == NULL)
+ {
+ blocks[i] = block;
+ break;
+ }
+ }
+
return mem;
}
}
@@ -520,12 +547,29 @@ dbus_malloc0 (size_t bytes)
#endif
else
{
+ struct block *block;
+ int i;
void *mem;
- mem = calloc (bytes, 1);
+
+ block = calloc (sizeof (struct block) + bytes + 256, 1);
+ block->size = bytes;
+ block->number_of_symbols = backtrace (block->symbols, 100);
+ mem = &block->memory;
+
#ifdef DBUS_BUILD_TESTS
if (mem)
_dbus_atomic_inc (&n_blocks_outstanding);
#endif
+
+ for (i = 0; i < sizeof(blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] == NULL)
+ {
+ blocks[i] = block;
+ break;
+ }
+ }
+
return mem;
}
}
@@ -597,12 +641,42 @@ dbus_realloc (void *memory,
#endif
else
{
+ struct block *block;
+ int i;
void *mem;
- mem = realloc (memory, bytes);
+
+ if (memory != NULL)
+ {
+ block = (struct block *) (((char *) memory) - offsetof (struct block, memory));
+
+ for (i = 0; i < sizeof(blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] == block)
+ {
+ blocks[i] = NULL;
+ break;
+ }
+ }
+ } else block = NULL;
+
+ block = realloc (block, bytes + sizeof (struct block) + 256);
+ block->size = bytes;
+ block->number_of_symbols = backtrace (block->symbols, 100);
+
+ mem = &block->memory;
#ifdef DBUS_BUILD_TESTS
if (memory == NULL && mem != NULL)
_dbus_atomic_inc (&n_blocks_outstanding);
#endif
+
+ for (i = 0; i < sizeof(blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] == NULL)
+ {
+ blocks[i] = block;
+ break;
+ }
+ }
return mem;
}
}
@@ -635,13 +709,26 @@ dbus_free (void *memory)
if (memory) /* we guarantee it's safe to free (NULL) */
{
+ int i;
+ struct block *block;
#ifdef DBUS_BUILD_TESTS
_dbus_atomic_dec (&n_blocks_outstanding);
_dbus_assert (n_blocks_outstanding.value >= 0);
#endif
- free (memory);
+ block = (struct block *) (((char *) memory) - offsetof (struct block, memory));
+
+ for (i = 0; i < sizeof(blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] == block)
+ {
+ blocks[i] = NULL;
+ break;
+ }
+ }
+
+ free (block);
}
}
@@ -744,6 +831,29 @@ _dbus_register_shutdown_func (DBusShutdownFunction func,
*
* @{
*/
+static void
+print_leaks (void)
+{
+ if (n_blocks_outstanding.value != 0)
+ {
+ int i;
+
+ int found = 0;
+ for (i = 0; i < sizeof(blocks)/sizeof(*blocks); i++)
+ {
+ if (blocks[i] != NULL)
+ {
+ struct block *block;
+ fprintf (stderr, "found leak\n");
+ block = blocks[i];
+ backtrace_symbols_fd (block->symbols, block->number_of_symbols, 2);
+ fprintf (stderr, "--\n");
+ found =1 ;
+ }
+ }
+ if (!found) fprintf (stderr, "no leaks found\n");
+ }
+}
/**
* Frees all memory allocated internally by libdbus and
@@ -798,6 +908,7 @@ dbus_shutdown (void)
}
_dbus_current_generation += 1;
+ print_leaks ();
}
/** @} */ /** End of public API docs block */