diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-09-28 23:30:14 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:59:29 -0500 |
commit | facfe8867d0f69f194d375a81f54dcb4eb91334e (patch) | |
tree | e7f574520969b85d1f36e4f0ee66c38377c97adf | |
parent | 361f7cc31e4f06ea0ef7ec93158484bef06e221a (diff) | |
download | samba-facfe8867d0f69f194d375a81f54dcb4eb91334e.tar.gz samba-facfe8867d0f69f194d375a81f54dcb4eb91334e.tar.bz2 samba-facfe8867d0f69f194d375a81f54dcb4eb91334e.zip |
r2742: - fixed a bug in talloc_unreference()
- made the LOCAL-TALLOC smbtorture test much stricter, checking that
block counts for every pointer are correct after every operation
(This used to be commit 18d3e2647f0bedbba699d1ba2649c0cfe4526ef6)
-rw-r--r-- | source4/lib/talloc.c | 6 | ||||
-rw-r--r-- | source4/torture/local/talloc.c | 154 |
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; } |