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 8 class MyClass 9 { 10 public: 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. 18 struct Ae 19 { 20 virtual ~Ae() 21 { fprintf(stderr, "destruct Ae\n"); 22 } 23 }; 24 struct Be 25 { 26 virtual ~Be() 27 { fprintf(stderr, "destruct Be\n"); 28 } 29 }; 30 struct Ce : public Ae, public Be 31 { 32 virtual ~Ce() 33 { fprintf(stderr, "destruct Ce\n"); 34 } 35 }; 36 37 struct A 38 { 39 char a; 40 A() 41 { a = 'a'; 42 } 43 virtual ~A() 44 { fprintf(stderr, "destruct A\n"); 45 } 46 }; 47 struct B 48 { 49 char b; 50 B() 51 { b = 'b'; 52 } 53 virtual ~B() 54 { fprintf(stderr, "destruct B\n"); 55 } 56 }; 57 struct 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 68 std::string str; 69 std::string str2; 70 MyClass *ptr; 71 MyClass *ptr2; 72 Be *ptrBCe; 73 Ae *ptrACe; 74 B *ptrBC; 75 A *ptrAC; 76 77 char who_points_at_cmd[100]; 78 79 void 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 102 int 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