leak-cases.c revision 8225cc0de2ccf390127b5910dceb7c6185091a38
18225cc0de2ccf390127b5910dceb7c6185091a38njn#include <stdio.h>
28225cc0de2ccf390127b5910dceb7c6185091a38njn#include <stdlib.h>
38225cc0de2ccf390127b5910dceb7c6185091a38njn#include "leak.h"
48225cc0de2ccf390127b5910dceb7c6185091a38njn#include "../memcheck.h"
58225cc0de2ccf390127b5910dceb7c6185091a38njn
68225cc0de2ccf390127b5910dceb7c6185091a38njn// Pointer chain          AAA Category/output BBB Category/output
78225cc0de2ccf390127b5910dceb7c6185091a38njn// -------------          ------------------- ------------
88225cc0de2ccf390127b5910dceb7c6185091a38njn// p1 ---> AAA            DR / R
98225cc0de2ccf390127b5910dceb7c6185091a38njn// p2 ---> AAA ---> BBB   DR / R              IR / R
108225cc0de2ccf390127b5910dceb7c6185091a38njn// p3      AAA            DL / L
118225cc0de2ccf390127b5910dceb7c6185091a38njn// p4      AAA ---> BBB   DL / I              IL / L
128225cc0de2ccf390127b5910dceb7c6185091a38njn// p5 -?-> AAA            (y)DR, (n)DL / P
138225cc0de2ccf390127b5910dceb7c6185091a38njn// p6 ---> AAA -?-> BBB   DR / R              (y)IR, (n)DL / P
148225cc0de2ccf390127b5910dceb7c6185091a38njn// p7 -?-> AAA ---> BBB   (y)DR, (n)DL / P    (y)IR, (n)IL / P
158225cc0de2ccf390127b5910dceb7c6185091a38njn// p8 -?-> AAA -?-> BBB   (y)DR, (n)DL / P    (y,y)IR, (n,y)IL, (_,n)DL / P
168225cc0de2ccf390127b5910dceb7c6185091a38njn// p9      AAA -?-> BBB   DL / L              (y)IL, (n)DL / I
178225cc0de2ccf390127b5910dceb7c6185091a38njn//
188225cc0de2ccf390127b5910dceb7c6185091a38njn// Pointer chain legend:
198225cc0de2ccf390127b5910dceb7c6185091a38njn// - pN: a root set pointer
208225cc0de2ccf390127b5910dceb7c6185091a38njn// - AAA, BBB: heap blocks
218225cc0de2ccf390127b5910dceb7c6185091a38njn// - --->: a start-pointer
228225cc0de2ccf390127b5910dceb7c6185091a38njn// - -?->: an interior-pointer
238225cc0de2ccf390127b5910dceb7c6185091a38njn//
248225cc0de2ccf390127b5910dceb7c6185091a38njn// Category legend:
258225cc0de2ccf390127b5910dceb7c6185091a38njn// - DR: Directly reachable
268225cc0de2ccf390127b5910dceb7c6185091a38njn// - IR: Indirectly reachable
278225cc0de2ccf390127b5910dceb7c6185091a38njn// - DL: Directly lost
288225cc0de2ccf390127b5910dceb7c6185091a38njn// - IL: Indirectly lost
298225cc0de2ccf390127b5910dceb7c6185091a38njn// - (y)XY: it's XY if the interior-pointer is a real pointer
308225cc0de2ccf390127b5910dceb7c6185091a38njn// - (n)XY: it's XY if the interior-pointer is not a real pointer
318225cc0de2ccf390127b5910dceb7c6185091a38njn// - (_)XY: it's XY in either case
328225cc0de2ccf390127b5910dceb7c6185091a38njn//
338225cc0de2ccf390127b5910dceb7c6185091a38njn// How we handle the 9 cases:
348225cc0de2ccf390127b5910dceb7c6185091a38njn// - "directly lost":    case 3
358225cc0de2ccf390127b5910dceb7c6185091a38njn// - "indirectly lost":  cases 4, 9
368225cc0de2ccf390127b5910dceb7c6185091a38njn// - "possibly lost":    cases 5..8
378225cc0de2ccf390127b5910dceb7c6185091a38njn// - "still reachable":  cases 1, 2
388225cc0de2ccf390127b5910dceb7c6185091a38njn
398225cc0de2ccf390127b5910dceb7c6185091a38njn
408225cc0de2ccf390127b5910dceb7c6185091a38njntypedef
418225cc0de2ccf390127b5910dceb7c6185091a38njn   struct _Node {
428225cc0de2ccf390127b5910dceb7c6185091a38njn      struct _Node* next;
438225cc0de2ccf390127b5910dceb7c6185091a38njn      // Padding ensures the structu is the same size on 32-bit and 64-bit
448225cc0de2ccf390127b5910dceb7c6185091a38njn      // machines.
458225cc0de2ccf390127b5910dceb7c6185091a38njn      char padding[8 - sizeof(struct _Node*)];
468225cc0de2ccf390127b5910dceb7c6185091a38njn   } Node;
478225cc0de2ccf390127b5910dceb7c6185091a38njn
488225cc0de2ccf390127b5910dceb7c6185091a38njnNode* mk(Node* next)
498225cc0de2ccf390127b5910dceb7c6185091a38njn{
508225cc0de2ccf390127b5910dceb7c6185091a38njn   // We allocate two nodes, so we can do p+1 and still point within the
518225cc0de2ccf390127b5910dceb7c6185091a38njn   // block.
528225cc0de2ccf390127b5910dceb7c6185091a38njn   Node* x = malloc(2 * sizeof(Node));
538225cc0de2ccf390127b5910dceb7c6185091a38njn   x->next = next;
548225cc0de2ccf390127b5910dceb7c6185091a38njn   return x;
558225cc0de2ccf390127b5910dceb7c6185091a38njn}
568225cc0de2ccf390127b5910dceb7c6185091a38njn
578225cc0de2ccf390127b5910dceb7c6185091a38njn// These are definite roots.
588225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p1;
598225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p2;
608225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p3;
618225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p4;
628225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p5;
638225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p6;
648225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p7;
658225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p8;
668225cc0de2ccf390127b5910dceb7c6185091a38njnNode* p9;
678225cc0de2ccf390127b5910dceb7c6185091a38njn
688225cc0de2ccf390127b5910dceb7c6185091a38njnint main(void)
698225cc0de2ccf390127b5910dceb7c6185091a38njn{
708225cc0de2ccf390127b5910dceb7c6185091a38njn   DECLARE_LEAK_COUNTERS;
718225cc0de2ccf390127b5910dceb7c6185091a38njn
728225cc0de2ccf390127b5910dceb7c6185091a38njn   GET_INITIAL_LEAK_COUNTS;
738225cc0de2ccf390127b5910dceb7c6185091a38njn
748225cc0de2ccf390127b5910dceb7c6185091a38njn   p1 = mk(NULL);       // Case 1: 16/1 still reachable
758225cc0de2ccf390127b5910dceb7c6185091a38njn
768225cc0de2ccf390127b5910dceb7c6185091a38njn   p2 = mk(mk(NULL));   // Case 2: 16/1 still reachable
778225cc0de2ccf390127b5910dceb7c6185091a38njn                                // 16/1 still reachable
788225cc0de2ccf390127b5910dceb7c6185091a38njn   (void)mk(NULL);      // Case 3: 16/1 definitely lost
798225cc0de2ccf390127b5910dceb7c6185091a38njn
808225cc0de2ccf390127b5910dceb7c6185091a38njn   (void)mk(mk(NULL));  // Case 4: 16/1 indirectly lost (counted again below!)
818225cc0de2ccf390127b5910dceb7c6185091a38njn                                // 32(16d,16i)/1 definitely lost (double count!)
828225cc0de2ccf390127b5910dceb7c6185091a38njn   p5 = mk(NULL);       // Case 5: 16/1 possibly lost (ok)
838225cc0de2ccf390127b5910dceb7c6185091a38njn   p5++;
848225cc0de2ccf390127b5910dceb7c6185091a38njn
858225cc0de2ccf390127b5910dceb7c6185091a38njn   p6 = mk(mk(NULL));   // Case 6: 16/1 still reachable
868225cc0de2ccf390127b5910dceb7c6185091a38njn   (p6->next)++;                // 16/1 possibly lost
878225cc0de2ccf390127b5910dceb7c6185091a38njn
888225cc0de2ccf390127b5910dceb7c6185091a38njn   p7 = mk(mk(NULL));   // Case 7: 16/1 possibly lost
898225cc0de2ccf390127b5910dceb7c6185091a38njn   p7++;                        // 16/1 possibly lost
908225cc0de2ccf390127b5910dceb7c6185091a38njn
918225cc0de2ccf390127b5910dceb7c6185091a38njn   p8 = mk(mk(NULL));   // Case 8: 16/1 possibly lost
928225cc0de2ccf390127b5910dceb7c6185091a38njn   (p8->next)++;                // 16/1 possibly lost
938225cc0de2ccf390127b5910dceb7c6185091a38njn   p8++;
948225cc0de2ccf390127b5910dceb7c6185091a38njn
958225cc0de2ccf390127b5910dceb7c6185091a38njn   p9 = mk(mk(NULL));   // Case 9: 16/1 indirectly lost (counted again below!)
968225cc0de2ccf390127b5910dceb7c6185091a38njn   (p9->next)++;                // 32(16d,16i)/1 definitely lost (double count!)
978225cc0de2ccf390127b5910dceb7c6185091a38njn   p9 = NULL;
988225cc0de2ccf390127b5910dceb7c6185091a38njn
998225cc0de2ccf390127b5910dceb7c6185091a38njn   GET_FINAL_LEAK_COUNTS;
1008225cc0de2ccf390127b5910dceb7c6185091a38njn
1018225cc0de2ccf390127b5910dceb7c6185091a38njn   PRINT_LEAK_COUNTS(stderr);
1028225cc0de2ccf390127b5910dceb7c6185091a38njn
1038225cc0de2ccf390127b5910dceb7c6185091a38njn   return 0;
1048225cc0de2ccf390127b5910dceb7c6185091a38njn}
105