1b94fbf083cf82802c9aa7c7a1192be75259cb691philippe#define __STDC_FORMAT_MACROS 28eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include <inttypes.h> 3ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <stdio.h> 4ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <unistd.h> 57c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe#include <stdint.h> 67c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe#include <stdlib.h> 7ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include <string> 85bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe#include <sstream> 9ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe#include "../memcheck.h" 10ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// Derived from test provided by Timur Iskhodzhanov (bug 280271) 11ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 12ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippeclass MyClass 13ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 147c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe char m1; 157c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe int m2; 16ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippepublic: 17ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe ~MyClass() 18ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct MyClass\n"); 19ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 20ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 21ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 22ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// Two hierarchies using MI, one with no fields, 23ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe// the other one with some data. 24ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Ae 25ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 26ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Ae() 27ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Ae\n"); 28ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 29ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 30ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Be 31ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 32ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Be() 33ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Be\n"); 34ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 35ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 36ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct Ce : public Ae, public Be 37ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 38ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~Ce() 39ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct Ce\n"); 40ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 41ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 42ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 43ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct A 44ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 45ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char a; 46ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe A() 47ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { a = 'a'; 48ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 49ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~A() 50ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct A\n"); 51ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 52ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 53ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct B 54ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 55ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char b; 56ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe B() 57ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { b = 'b'; 58ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 59ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~B() 60ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct B\n"); 61ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 62ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 63ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippestruct C : public A, public B 64ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe{ 65ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe char c; 66ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe C() 67ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { c = 'c'; 68ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 69ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe virtual ~C() 70ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe { fprintf(stderr, "destruct C\n"); 71ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe } 72ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe}; 73ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 747c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid* wrap64_malloc(int size) 757c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe{ 767c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe uint64_t *p = (uint64_t*)malloc(size + 8); 777c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe *p = size; 787c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe ++p; 797c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe return p; 807c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe} 817c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 827c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid wrap64_free(void *p) 837c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe{ 847c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe uint64_t *p2 = (uint64_t*)p; 857c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe if (p2 == NULL) 867c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe return; 877c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe --p2; 887c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe free(p2); 897c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe} 907c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 91671b0232c307abd80ef4da890c2b00e778751359philippestd::string str; 92671b0232c307abd80ef4da890c2b00e778751359philippestd::string str2; 93671b0232c307abd80ef4da890c2b00e778751359philippeMyClass *ptr; 94671b0232c307abd80ef4da890c2b00e778751359philippeMyClass *ptr2; 95671b0232c307abd80ef4da890c2b00e778751359philippeBe *ptrBCe; 96671b0232c307abd80ef4da890c2b00e778751359philippeAe *ptrACe; 97671b0232c307abd80ef4da890c2b00e778751359philippeB *ptrBC; 98671b0232c307abd80ef4da890c2b00e778751359philippeA *ptrAC; 997c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippevoid* ptr64; 100671b0232c307abd80ef4da890c2b00e778751359philippe 1015bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippechar who_points_at_cmd[100]; 102ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 103671b0232c307abd80ef4da890c2b00e778751359philippevoid doit(void) 104671b0232c307abd80ef4da890c2b00e778751359philippe{ 105671b0232c307abd80ef4da890c2b00e778751359philippe str = "Valgrind"; // interior ptr. 106671b0232c307abd80ef4da890c2b00e778751359philippe str2 = str; 107671b0232c307abd80ef4da890c2b00e778751359philippe ptr = new MyClass[3]; // interior ptr. 1087c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe ptr64 = wrap64_malloc(23); 1095bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 1105bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // prepare the who_points_at cmd we will run. 1115bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // Do it here to avoid having ptr or its exterior ptr kept in a register. 1128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sprintf(who_points_at_cmd, "who_points_at %#" PRIxPTR " 20", 1138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (uintptr_t) (char*)ptr - sizeof(void*)); 1145bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 115671b0232c307abd80ef4da890c2b00e778751359philippe ptr2 = new MyClass[0]; // "interior but exterior ptr". 116671b0232c307abd80ef4da890c2b00e778751359philippe // ptr2 points after the chunk, is wrongly considered by memcheck as definitely leaked. 117ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 118671b0232c307abd80ef4da890c2b00e778751359philippe ptrBCe = new Ce; // interior ptr. 119671b0232c307abd80ef4da890c2b00e778751359philippe ptrACe = new Ce; // not an interior pointer. 120671b0232c307abd80ef4da890c2b00e778751359philippe ptrBC = new C; // interior ptr. 121671b0232c307abd80ef4da890c2b00e778751359philippe ptrAC = new C; // not an interior pointer. 122671b0232c307abd80ef4da890c2b00e778751359philippe 123671b0232c307abd80ef4da890c2b00e778751359philippe 124671b0232c307abd80ef4da890c2b00e778751359philippe str2 += " rocks (str2)\n"; // interior ptr. 125671b0232c307abd80ef4da890c2b00e778751359philippe} 126ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 127ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 128671b0232c307abd80ef4da890c2b00e778751359philippeint main() { 129671b0232c307abd80ef4da890c2b00e778751359philippe 130671b0232c307abd80ef4da890c2b00e778751359philippe doit(); 13106bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("v.set log_output"); 132ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 133ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "VALGRIND_DO_LEAK_CHECK\n"); 134ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe VALGRIND_DO_LEAK_CHECK; // All possible leaks should be detected, giving only reachable data. 135ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 136ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe // Check individually each heuristic 137ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary heuristics multipleinheritance\n"); 13806bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance"); 139ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary any heuristics newarray\n"); 14006bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics newarray"); 1417c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics length64\n"); 1427c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics length64"); 143ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "leak_check summary heuristics stdstring\n"); 14406bc722457ffe12e056d2f40d0d2f5c8711b541fflorian (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics stdstring"); 145ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 1467c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe // check all and none 1477c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics multipleinheritance,newarray,stdstring,length64\n"); 1487c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics multipleinheritance,newarray,stdstring,length64"); 1497c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics all\n"); 1507c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics all"); 1517c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe fprintf(stderr, "leak_check summary heuristics none\n"); 1527c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe (void) VALGRIND_MONITOR_COMMAND("leak_check summary heuristics none"); 1537c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe 1545bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe // Test the who_points_at when the block is pointed to with an interior ptr. 1555bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe (void) VALGRIND_MONITOR_COMMAND(who_points_at_cmd); 1565bd40601a929e8216b1c4b98d5048dddd2c2c20ephilippe 157ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete [] ptr; 158ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete [] ptr2; 159ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrBCe; 160ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrACe; 161ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrBC; 162ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe delete ptrAC; 1637c69a3edda5335fa4c60f8161252b4bab8a76f7ephilippe wrap64_free(ptr64); 164ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe fprintf(stderr, "Finished!\n"); 165ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe return 0; 166ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe} 167ab1fce9bfb9742bffdfbd7ea9e4dad04ffb17819philippe 168