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