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
10class MyClass
11{
12   char m1;
13   int  m2;
14public:
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.
22struct Ae
23{
24   virtual ~Ae()
25   { fprintf(stderr, "destruct Ae\n");
26   }
27};
28struct Be
29{
30   virtual ~Be()
31   { fprintf(stderr, "destruct Be\n");
32   }
33};
34struct Ce : public Ae, public Be
35{
36   virtual ~Ce()
37   { fprintf(stderr, "destruct Ce\n");
38   }
39};
40
41struct A
42{
43   char a;
44   A()
45   { a = 'a';
46   }
47   virtual ~A()
48   { fprintf(stderr, "destruct A\n");
49   }
50};
51struct B
52{
53   char b;
54   B()
55   { b = 'b';
56   }
57   virtual ~B()
58   { fprintf(stderr, "destruct B\n");
59   }
60};
61struct C : public A, public B
62{
63   char c;
64   C()
65   { c = 'c';
66   }
67   virtual ~C()
68   { fprintf(stderr, "destruct C\n");
69   }
70};
71
72void* wrap64_malloc(int size)
73{
74  uint64_t *p = (uint64_t*)malloc(size + 8);
75  *p = size;
76  ++p;
77  return p;
78}
79
80void 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
89std::string str;
90std::string str2;
91MyClass *ptr;
92MyClass *ptr2;
93Be *ptrBCe;
94Ae *ptrACe;
95B *ptrBC;
96A *ptrAC;
97void* ptr64;
98
99char who_points_at_cmd[100];
100
101void 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
125int 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