mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
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 commit is contained in:
parent
0bb42ba898
commit
18d3e2647f
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user