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