summaryrefslogtreecommitdiff
path: root/source4/lib/talloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/talloc.c')
-rw-r--r--source4/lib/talloc.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/source4/lib/talloc.c b/source4/lib/talloc.c
index c236834d91..114d0de43b 100644
--- a/source4/lib/talloc.c
+++ b/source4/lib/talloc.c
@@ -30,6 +30,8 @@
#define TALLOC_MAGIC 0xe814ec4f
#define TALLOC_MAGIC_FREE 0x7faebef3
+static void *null_context;
+
struct talloc_chunk {
struct talloc_chunk *next, *prev;
struct talloc_chunk *parent, *child;
@@ -61,6 +63,10 @@ void *talloc(void *context, size_t size)
{
struct talloc_chunk *tc;
+ if (context == NULL) {
+ context = null_context;
+ }
+
if (size >= MAX_TALLOC_SIZE) {
return NULL;
}
@@ -165,6 +171,18 @@ void *talloc_named(void *context, size_t size,
}
/*
+ return the name of a talloc ptr, or "UNNAMED"
+*/
+const char *talloc_get_name(void *ptr)
+{
+ struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
+ if (tc->name) {
+ return tc->name;
+ }
+ return "UNNAMED";
+}
+
+/*
this is for compatibility with older versions of talloc
*/
void *talloc_init(const char *fmt, ...) _PRINTF_ATTRIBUTE(1,2)
@@ -327,7 +345,7 @@ void *talloc_steal(void *new_ctx, void *ptr)
/*
return the total size of a talloc pool (subtree)
*/
-off_t talloc_total_size(void *ptr)
+static off_t talloc_total_size(void *ptr)
{
off_t total = 0;
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
@@ -339,6 +357,58 @@ off_t talloc_total_size(void *ptr)
return total;
}
+/*
+ return the total number of blocks in a talloc pool (subtree)
+*/
+static off_t talloc_total_blocks(void *ptr)
+{
+ off_t total = 0;
+ struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+ total++;
+ for (c=tc->child;c;c=c->next) {
+ total += talloc_total_blocks(c+1);
+ }
+ return total;
+}
+
+/*
+ report on memory usage by all children of a pointer
+*/
+void talloc_report(void *ptr, FILE *f)
+{
+ struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
+
+ fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
+ talloc_get_name(ptr),
+ (unsigned long)talloc_total_size(ptr),
+ (unsigned long)talloc_total_blocks(ptr));
+
+ for (c=tc->child;c;c=c->next) {
+ fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
+ talloc_get_name(c+1),
+ (unsigned long)talloc_total_size(c+1),
+ (unsigned long)talloc_total_blocks(c+1));
+ }
+
+}
+
+/*
+ report on any memory hanging off the null context
+*/
+static void talloc_report_all(void)
+{
+ talloc_report(null_context, stderr);
+}
+
+/*
+ enable leak reporting on exit
+*/
+void talloc_enable_leak_check(void)
+{
+ null_context = talloc_named(NULL, 0, "null_context");
+ atexit(talloc_report_all);
+}
/*
talloc and zero memory.