1#include <stdio.h> 2#include <unistd.h> 3#include <string> 4#include <sstream> 5#include "../memcheck.h" 6// Derived from test provided by Timur Iskhodzhanov (bug 280271) 7 8class MyClass 9{ 10public: 11 ~MyClass() 12 { fprintf(stderr, "destruct MyClass\n"); 13 } 14}; 15 16// Two hierarchies using MI, one with no fields, 17// the other one with some data. 18struct Ae 19{ 20 virtual ~Ae() 21 { fprintf(stderr, "destruct Ae\n"); 22 } 23}; 24struct Be 25{ 26 virtual ~Be() 27 { fprintf(stderr, "destruct Be\n"); 28 } 29}; 30struct Ce : public Ae, public Be 31{ 32 virtual ~Ce() 33 { fprintf(stderr, "destruct Ce\n"); 34 } 35}; 36 37struct A 38{ 39 char a; 40 A() 41 { a = 'a'; 42 } 43 virtual ~A() 44 { fprintf(stderr, "destruct A\n"); 45 } 46}; 47struct B 48{ 49 char b; 50 B() 51 { b = 'b'; 52 } 53 virtual ~B() 54 { fprintf(stderr, "destruct B\n"); 55 } 56}; 57struct C : public A, public B 58{ 59 char c; 60 C() 61 { c = 'c'; 62 } 63 virtual ~C() 64 { fprintf(stderr, "destruct C\n"); 65 } 66}; 67 68std::string str; 69std::string str2; 70MyClass *ptr; 71MyClass *ptr2; 72Be *ptrBCe; 73Ae *ptrACe; 74B *ptrBC; 75A *ptrAC; 76 77char who_points_at_cmd[100]; 78 79void doit(void) 80{ 81 str = "Valgrind"; // interior ptr. 82 str2 = str; 83 ptr = new MyClass[3]; // interior ptr. 84 85 // prepare the who_points_at cmd we will run. 86 // Do it here to avoid having ptr or its exterior ptr kept in a register. 87 sprintf(who_points_at_cmd, "who_points_at %p 20", (char*)ptr - sizeof(void*)); 88 89 ptr2 = new MyClass[0]; // "interior but exterior ptr". 90 // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked. 91 92 ptrBCe = new Ce; // interior ptr. 93 ptrACe = new Ce; // not an interior pointer. 94 ptrBC = new C; // interior ptr. 95 ptrAC = new C; // not an interior pointer. 96 97 98 str2 += " rocks (str2)\n"; // interior ptr. 99} 100 101 102int main() { 103 104 doit(); 105 (void) VALGRIND_MONITOR_COMMAND("v.set log_output"); 106 107 fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n"); 108 VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data. 109 110 // Check individually each heuristic 111 fprintf(stderr, "leak_check summary heuristics multipleinheritance\n"); 112 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance"); 113 fprintf(stderr, "leak_check summary any heuristics newarray\n"); 114 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray"); 115 fprintf(stderr, "leak_check summary heuristics stdstring\n"); 116 (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring"); 117 118 // Test the who_points_at when the block is pointed to with an interior ptr. 119 (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd); 120 121 delete [] ptr; 122 delete [] ptr2; 123 delete ptrBCe; 124 delete ptrACe; 125 delete ptrBC; 126 delete ptrAC; 127 fprintf(stderr, "Finished!\n"); 128 return 0; 129} 130 131