Home | History | Annotate | Download | only in tests
      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 
     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 
     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 
     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