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