• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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