1 #define _GLIBCXX_USE_CXX11_ABI 0
2 #define __STDC_FORMAT_MACROS
3 #include <inttypes.h>
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string>
9 #include <sstream>
10 #include "../memcheck.h"
11 // Derived from test provided by Timur Iskhodzhanov (bug 280271)
12 
13 class MyClass
14 {
15    char m1;
16    int  m2;
17 public:
~MyClass()18    ~MyClass()
19    { fprintf(stderr, "destruct MyClass\n");
20    }
21 };
22 
23 // Two hierarchies using MI, one with no fields,
24 // the other one with some data.
25 struct Ae
26 {
~AeAe27    virtual ~Ae()
28    { fprintf(stderr, "destruct Ae\n");
29    }
30 };
31 struct Be
32 {
~BeBe33    virtual ~Be()
34    { fprintf(stderr, "destruct Be\n");
35    }
36 };
37 struct Ce : public Ae, public Be
38 {
~CeCe39    virtual ~Ce()
40    { fprintf(stderr, "destruct Ce\n");
41    }
42 };
43 
44 struct A
45 {
46    char a;
AA47    A()
48    { a = 'a';
49    }
~AA50    virtual ~A()
51    { fprintf(stderr, "destruct A\n");
52    }
53 };
54 struct B
55 {
56    char b;
BB57    B()
58    { b = 'b';
59    }
~BB60    virtual ~B()
61    { fprintf(stderr, "destruct B\n");
62    }
63 };
64 struct C : public A, public B
65 {
66    char c;
CC67    C()
68    { c = 'c';
69    }
~CC70    virtual ~C()
71    { fprintf(stderr, "destruct C\n");
72    }
73 };
74 
wrap64_malloc(int size)75 void* wrap64_malloc(int size)
76 {
77   uint64_t *p = (uint64_t*)malloc(size + 8);
78   *p = size;
79   ++p;
80   return p;
81 }
82 
wrap64_free(void * p)83 void wrap64_free(void *p)
84 {
85   uint64_t *p2 = (uint64_t*)p;
86   if (p2 == NULL)
87     return;
88   --p2;
89   free(p2);
90 }
91 
92 std::string str;
93 std::string str2;
94 MyClass *ptr;
95 MyClass *ptr2;
96 Be *ptrBCe;
97 Ae *ptrACe;
98 B *ptrBC;
99 A *ptrAC;
100 void* ptr64;
101 
102 char who_points_at_cmd[100];
103 
doit(void)104 void doit(void)
105 {
106   str = "Valgrind"; // interior ptr.
107   str2 = str;
108   ptr = new MyClass[3]; // interior ptr.
109   ptr64 = wrap64_malloc(23);
110 
111   // prepare the who_points_at cmd we will run.
112   // Do it here to avoid having ptr or its exterior ptr kept in a register.
113   sprintf(who_points_at_cmd, "who_points_at %#" PRIxPTR " 20",
114           (uintptr_t) (char*)ptr - sizeof(void*));
115 
116   ptr2 = new MyClass[0]; // "interior but exterior ptr".
117   // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked.
118 
119   ptrBCe = new Ce;  // interior ptr.
120   ptrACe = new Ce;  // not an interior pointer.
121   ptrBC = new C;  // interior ptr.
122   ptrAC = new C;  // not an interior pointer.
123 
124 
125   str2 += " rocks (str2)\n"; // interior ptr.
126 }
127 
128 
main()129 int main() {
130 
131    doit();
132    (void) VALGRIND_MONITOR_COMMAND("v.set log_output");
133 
134    fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n");
135    VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data.
136 
137    // Check individually each heuristic
138    fprintf(stderr, "leak_check summary heuristics multipleinheritance\n");
139    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance");
140    fprintf(stderr, "leak_check summary any heuristics newarray\n");
141    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray");
142    fprintf(stderr, "leak_check summary heuristics length64\n");
143    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics length64");
144    fprintf(stderr, "leak_check summary heuristics stdstring\n");
145    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring");
146 
147    // check all and none
148    fprintf(stderr, "leak_check summary heuristics multipleinheritance,newarray,stdstring,length64\n");
149    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance,newarray,stdstring,length64");
150    fprintf(stderr, "leak_check summary heuristics all\n");
151    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics all");
152    fprintf(stderr, "leak_check summary heuristics none\n");
153    (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics none");
154 
155    // Test the who_points_at when the block is pointed to with an interior ptr.
156    (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd);
157 
158    delete [] ptr;
159    delete [] ptr2;
160    delete ptrBCe;
161    delete ptrACe;
162    delete ptrBC;
163    delete ptrAC;
164    wrap64_free(ptr64);
165    fprintf(stderr, "Finished!\n");
166    return 0;
167 }
168 
169