1ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <stdio.h> 2ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <unistd.h> 37c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe#include <stdint.h> 47c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe#include <stdlib.h> 5ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <string> 65bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe#include <sstream> 7ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include "../memcheck.h" 8ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// Derived from test provided by Timur Iskhodzhanov (bug 280271) 9ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 10ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippeclass MyClass 11ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 127c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe char m1; 137c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe int m2; 14ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippepublic: 15ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe ~MyClass() 16ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct MyClass\n"); 17ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 18ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 19ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 20ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// Two hierarchies using MI, one with no fields, 21ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// the other one with some data. 22ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Ae 23ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 24ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Ae() 25ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Ae\n"); 26ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 27ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 28ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Be 29ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 30ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Be() 31ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Be\n"); 32ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 33ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 34ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Ce : public Ae, public Be 35ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 36ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Ce() 37ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Ce\n"); 38ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 39ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 40ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 41ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct A 42ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 43ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char a; 44ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe A() 45ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { a = 'a'; 46ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 47ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~A() 48ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct A\n"); 49ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 50ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 51ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct B 52ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 53ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char b; 54ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe B() 55ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { b = 'b'; 56ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 57ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~B() 58ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct B\n"); 59ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 60ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 61ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct C : public A, public B 62ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 63ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char c; 64ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe C() 65ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { c = 'c'; 66ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 67ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~C() 68ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct C\n"); 69ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 70ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 71ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 727c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid* wrap64_malloc(int size) 737c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe{ 747c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe uint64_t *p = (uint64_t*)malloc(size + 8); 757c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe *p = size; 767c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe ++p; 777c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe return p; 787c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe} 797c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 807c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid wrap64_free(void *p) 817c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe{ 827c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe uint64_t *p2 = (uint64_t*)p; 837c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe if (p2 == NULL) 847c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe return; 857c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe --p2; 867c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe free(p2); 877c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe} 887c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 89671b0232c307abd80ef4da890c2b00e778751359philippestd::string str; 90671b0232c307abd80ef4da890c2b00e778751359philippestd::string str2; 91671b0232c307abd80ef4da890c2b00e778751359philippeMyClass *ptr; 92671b0232c307abd80ef4da890c2b00e778751359philippeMyClass *ptr2; 93671b0232c307abd80ef4da890c2b00e778751359philippeBe *ptrBCe; 94671b0232c307abd80ef4da890c2b00e778751359philippeAe *ptrACe; 95671b0232c307abd80ef4da890c2b00e778751359philippeB *ptrBC; 96671b0232c307abd80ef4da890c2b00e778751359philippeA *ptrAC; 977c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid* ptr64; 98671b0232c307abd80ef4da890c2b00e778751359philippe 995bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippechar who_points_at_cmd[100]; 100ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 101671b0232c307abd80ef4da890c2b00e778751359philippevoid doit(void) 102671b0232c307abd80ef4da890c2b00e778751359philippe{ 103671b0232c307abd80ef4da890c2b00e778751359philippe str = "Valgrind"; // interior ptr. 104671b0232c307abd80ef4da890c2b00e778751359philippe str2 = str; 105671b0232c307abd80ef4da890c2b00e778751359philippe ptr = new MyClass[3]; // interior ptr. 1067c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe ptr64 = wrap64_malloc(23); 1075bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 1085bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // prepare the who_points_at cmd we will run. 1095bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // Do it here to avoid having ptr or its exterior ptr kept in a register. 1105bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe sprintf(who_points_at_cmd, "who_points_at %p 20", (char*)ptr - sizeof(void*)); 1115bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 112671b0232c307abd80ef4da890c2b00e778751359philippe ptr2 = new MyClass[0]; // "interior but exterior ptr". 113671b0232c307abd80ef4da890c2b00e778751359philippe // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked. 114ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 115671b0232c307abd80ef4da890c2b00e778751359philippe ptrBCe = new Ce; // interior ptr. 116671b0232c307abd80ef4da890c2b00e778751359philippe ptrACe = new Ce; // not an interior pointer. 117671b0232c307abd80ef4da890c2b00e778751359philippe ptrBC = new C; // interior ptr. 118671b0232c307abd80ef4da890c2b00e778751359philippe ptrAC = new C; // not an interior pointer. 119671b0232c307abd80ef4da890c2b00e778751359philippe 120671b0232c307abd80ef4da890c2b00e778751359philippe 121671b0232c307abd80ef4da890c2b00e778751359philippe str2 += " rocks (str2)\n"; // interior ptr. 122671b0232c307abd80ef4da890c2b00e778751359philippe} 123ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 124ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 125671b0232c307abd80ef4da890c2b00e778751359philippeint main() { 126671b0232c307abd80ef4da890c2b00e778751359philippe 127671b0232c307abd80ef4da890c2b00e778751359philippe doit(); 12806bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("v.set log_output"); 129ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 130ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n"); 131ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data. 132ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 133ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe // Check individually each heuristic 134ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary heuristics multipleinheritance\n"); 13506bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance"); 136ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary any heuristics newarray\n"); 13706bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray"); 1387c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics length64\n"); 1397c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics length64"); 140ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary heuristics stdstring\n"); 14106bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring"); 142ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 1437c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe // check all and none 1447c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics multipleinheritance,newarray,stdstring,length64\n"); 1457c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance,newarray,stdstring,length64"); 1467c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics all\n"); 1477c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics all"); 1487c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics none\n"); 1497c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics none"); 1507c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 1515bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // Test the who_points_at when the block is pointed to with an interior ptr. 1525bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd); 1535bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 154ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete [] ptr; 155ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete [] ptr2; 156ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrBCe; 157ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrACe; 158ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrBC; 159ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrAC; 1607c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe wrap64_free(ptr64); 161ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "Finished!\n"); 162ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe return 0; 163ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe} 164ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 165