summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/talloc.c6
-rw-r--r--source4/torture/local/talloc.c154
2 files changed, 116 insertions, 44 deletions
diff --git a/source4/lib/talloc.c b/source4/lib/talloc.c
index 4b796fbbd0..b81cf7221b 100644
--- a/source4/lib/talloc.c
+++ b/source4/lib/talloc.c
@@ -196,8 +196,8 @@ void *talloc_unreference(const void *context, const void *ptr)
}
for (h=tc->refs;h;h=h->next) {
- const void *parent = talloc_parent_chunk(h);
- if (parent == context) break;
+ struct talloc_chunk *p = talloc_parent_chunk(h);
+ if ((p==NULL && context==NULL) || p+1 == context) break;
}
if (h == NULL) {
return NULL;
@@ -526,7 +526,7 @@ off_t talloc_total_size(const void *ptr)
/*
return the total number of blocks in a talloc pool (subtree)
*/
-static off_t talloc_total_blocks(const void *ptr)
+off_t talloc_total_blocks(const void *ptr)
{
off_t total = 0;
struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
diff --git a/source4/torture/local/talloc.c b/source4/torture/local/talloc.c
index 9f518eabf2..e046ae8dc5 100644
--- a/source4/torture/local/talloc.c
+++ b/source4/torture/local/talloc.c
@@ -22,42 +22,68 @@
#include "includes.h"
+#define CHECK_BLOCKS(ptr, tblocks) do { \
+ if (talloc_total_blocks(ptr) != (tblocks)) { \
+ printf("(%d) failed: wrong '%s' tree size: got %u expected %u\n", \
+ __LINE__, #ptr, \
+ (unsigned)talloc_total_blocks(ptr), \
+ (unsigned)tblocks); \
+ talloc_report_full(ptr, stdout); \
+ return False; \
+ } \
+} while (0)
+
/*
test references
*/
static BOOL test_ref1(void)
{
- void *p1, *p2, *ref, *r1;
+ void *root, *p1, *p2, *ref, *r1;
printf("TESTING SINGLE REFERENCE FREE\n");
- p1 = talloc_named_const(NULL, 1, "p1");
+ root = talloc_named_const(NULL, 0, "root");
+ p1 = talloc_named_const(root, 1, "p1");
p2 = talloc_named_const(p1, 1, "p2");
talloc_named_const(p1, 1, "x1");
- talloc_named_const(p1, 1, "x2");
- talloc_named_const(p1, 1, "x3");
+ talloc_named_const(p1, 2, "x2");
+ talloc_named_const(p1, 3, "x3");
- r1 = talloc_named_const(NULL, 1, "r1");
+ r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 2);
printf("Freeing p2\n");
talloc_free(p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(r1, 1);
printf("Freeing r1\n");
talloc_free(r1);
talloc_report_full(NULL, stdout);
- if (talloc_total_size(NULL) != 0) {
+ CHECK_BLOCKS(root, 1);
+
+ if (talloc_total_size(root) != 0) {
printf("failed: non-zero total size\n");
return False;
}
+ talloc_free(root);
+
return True;
}
@@ -66,41 +92,57 @@ static BOOL test_ref1(void)
*/
static BOOL test_ref2(void)
{
- void *p1, *p2, *ref, *r1;
+ void *root, *p1, *p2, *ref, *r1;
printf("TESTING DOUBLE REFERENCE FREE\n");
- p1 = talloc_named_const(NULL, 1, "p1");
+ root = talloc_named_const(NULL, 0, "root");
+ p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
p2 = talloc_named_const(p1, 1, "p2");
- r1 = talloc_named_const(NULL, 1, "r1");
+ r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 2);
printf("Freeing ref\n");
talloc_free(ref);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p2\n");
talloc_free(p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 4);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(r1, 1);
printf("Freeing r1\n");
talloc_free(r1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
- if (talloc_total_size(NULL) != 0) {
+ if (talloc_total_size(root) != 0) {
printf("failed: non-zero total size\n");
return False;
}
+ talloc_free(root);
+
return True;
}
@@ -109,32 +151,39 @@ static BOOL test_ref2(void)
*/
static BOOL test_ref3(void)
{
- void *p1, *p2, *ref, *r1;
+ void *root, *p1, *p2, *ref, *r1;
printf("TESTING PARENT REFERENCE FREE\n");
- p1 = talloc_named_const(NULL, 1, "p1");
- p2 = talloc_named_const(NULL, 1, "p2");
-
+ root = talloc_named_const(NULL, 0, "root");
+ p1 = talloc_named_const(root, 1, "p1");
+ p2 = talloc_named_const(root, 1, "p2");
r1 = talloc_named_const(p1, 1, "r1");
-
ref = talloc_reference(p2, r1);
+ talloc_report_full(root, stdout);
- talloc_report_full(NULL, stdout);
+ CHECK_BLOCKS(p1, 2);
+ CHECK_BLOCKS(p2, 2);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p2, 2);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p2\n");
talloc_free(p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
- if (talloc_total_size(NULL) != 0) {
+ if (talloc_total_size(root) != 0) {
printf("failed: non-zero total size\n");
return False;
}
+ talloc_free(root);
+
return True;
}
@@ -143,37 +192,49 @@ static BOOL test_ref3(void)
*/
static BOOL test_ref4(void)
{
- void *p1, *p2, *ref, *r1;
+ void *root, *p1, *p2, *ref, *r1;
printf("TESTING REFERRER REFERENCE FREE\n");
- p1 = talloc_named_const(NULL, 1, "p1");
+ root = talloc_named_const(NULL, 0, "root");
+ p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
p2 = talloc_named_const(p1, 1, "p2");
- r1 = talloc_named_const(NULL, 1, "r1");
+ r1 = talloc_named_const(root, 1, "r1");
ref = talloc_reference(r1, p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 2);
printf("Freeing r1\n");
talloc_free(r1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 5);
+ CHECK_BLOCKS(p2, 1);
printf("Freeing p2\n");
talloc_free(p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 4);
printf("Freeing p1\n");
talloc_free(p1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
- if (talloc_total_size(NULL) != 0) {
+ if (talloc_total_size(root) != 0) {
printf("failed: non-zero total size\n");
return False;
}
+ talloc_free(root);
+
return True;
}
@@ -183,11 +244,12 @@ static BOOL test_ref4(void)
*/
static BOOL test_unref1(void)
{
- void *p1, *p2, *ref, *r1;
+ void *root, *p1, *p2, *ref, *r1;
printf("TESTING UNREFERENCE\n");
- p1 = talloc_named_const(NULL, 1, "p1");
+ root = talloc_named_const(NULL, 0, "root");
+ p1 = talloc_named_const(root, 1, "p1");
talloc_named_const(p1, 1, "x1");
talloc_named_const(p1, 1, "x2");
talloc_named_const(p1, 1, "x3");
@@ -195,21 +257,31 @@ static BOOL test_unref1(void)
r1 = talloc_named_const(p1, 1, "r1");
ref = talloc_reference(r1, p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 7);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 2);
printf("Unreferencing r1\n");
talloc_unreference(r1, p2);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
+
+ CHECK_BLOCKS(p1, 6);
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(r1, 1);
printf("Freeing p1\n");
talloc_free(p1);
- talloc_report_full(NULL, stdout);
+ talloc_report_full(root, stdout);
- if (talloc_total_size(NULL) != 0) {
+ if (talloc_total_size(root) != 0) {
printf("failed: non-zero total size\n");
return False;
}
+ talloc_free(root);
+
return True;
}