File: leak_cpp_interior.cpp

package info (click to toggle)
valgrind 1%3A3.14.0-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 156,980 kB
  • sloc: ansic: 728,128; exp: 26,134; xml: 22,268; cpp: 7,638; asm: 7,312; makefile: 6,102; perl: 5,910; sh: 5,717
file content (168 lines) | stat: -rw-r--r-- 3,958 bytes parent folder | download
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;
}