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