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