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