1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "leak.h" 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "../memcheck.h" 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* We build this tree: 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown / \ 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown B C 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown / \ / \ 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D E F G 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Then we leak D and C-F-G. 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _Node { 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _Node *l; 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _Node *r; 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Padding ensures the structu is the same size on 32-bit and 64-bit 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // machines. 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char padding[16 - 2*sizeof(struct _Node*)]; 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } Node; 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownNode* mk(void) 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Node *x = malloc(sizeof(Node)); 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x->l = NULL; 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x->r = NULL; 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return x; 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This is a definite root. 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownNode* t; 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid f(void) 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Building like this rather than "t = mk(mk(mk(NULL, NULL), ...)" seems to 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // help avoid leaving pointers on the stack to supposedly-leaked blocks. 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t = mk(); // A 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->l = mk(); // B 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->r = mk(); // C (48(16d,32i)/1 definitely leaked from here) 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->l->l = mk(); // D (16/1 definitely leaked from here) 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->l->r = mk(); // E 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->r->l = mk(); // F 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->r->r = mk(); // G 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Sever B->D, leaking D 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->l->l = NULL; 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Sever A->C, leaking C-F-G 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown t->r = NULL; 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void) 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DECLARE_LEAK_COUNTERS; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GET_INITIAL_LEAK_COUNTS; 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // See leak-cases.c for why we do the work in f(). 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown f(); 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GET_FINAL_LEAK_COUNTS; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRINT_LEAK_COUNTS(stderr); 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72