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