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