|
@@ -0,0 +1,309 @@
|
|
1
|
+
|
|
2
|
+/*
|
|
3
|
+ ----------------------------------------------------------------
|
|
4
|
+
|
|
5
|
+ Notice that the following BSD-style license applies to this one
|
|
6
|
+ file (memcheck.h) only. The rest of Valgrind is licensed under the
|
|
7
|
+ terms of the GNU General Public License, version 2, unless
|
|
8
|
+ otherwise indicated. See the COPYING file in the source
|
|
9
|
+ distribution for details.
|
|
10
|
+
|
|
11
|
+ ----------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+ This file is part of MemCheck, a heavyweight Valgrind tool for
|
|
14
|
+ detecting memory errors.
|
|
15
|
+
|
|
16
|
+ Copyright (C) 2000-2010 Julian Seward. All rights reserved.
|
|
17
|
+
|
|
18
|
+ Redistribution and use in source and binary forms, with or without
|
|
19
|
+ modification, are permitted provided that the following conditions
|
|
20
|
+ are met:
|
|
21
|
+
|
|
22
|
+ 1. Redistributions of source code must retain the above copyright
|
|
23
|
+ notice, this list of conditions and the following disclaimer.
|
|
24
|
+
|
|
25
|
+ 2. The origin of this software must not be misrepresented; you must
|
|
26
|
+ not claim that you wrote the original software. If you use this
|
|
27
|
+ software in a product, an acknowledgment in the product
|
|
28
|
+ documentation would be appreciated but is not required.
|
|
29
|
+
|
|
30
|
+ 3. Altered source versions must be plainly marked as such, and must
|
|
31
|
+ not be misrepresented as being the original software.
|
|
32
|
+
|
|
33
|
+ 4. The name of the author may not be used to endorse or promote
|
|
34
|
+ products derived from this software without specific prior written
|
|
35
|
+ permission.
|
|
36
|
+
|
|
37
|
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
38
|
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
39
|
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
40
|
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
41
|
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
42
|
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
|
43
|
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
44
|
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
45
|
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
46
|
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
47
|
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
48
|
+
|
|
49
|
+ ----------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+ Notice that the above BSD-style license applies to this one file
|
|
52
|
+ (memcheck.h) only. The entire rest of Valgrind is licensed under
|
|
53
|
+ the terms of the GNU General Public License, version 2. See the
|
|
54
|
+ COPYING file in the source distribution for details.
|
|
55
|
+
|
|
56
|
+ ----------------------------------------------------------------
|
|
57
|
+*/
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+#ifndef __MEMCHECK_H
|
|
61
|
+#define __MEMCHECK_H
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+/* This file is for inclusion into client (your!) code.
|
|
65
|
+
|
|
66
|
+ You can use these macros to manipulate and query memory permissions
|
|
67
|
+ inside your own programs.
|
|
68
|
+
|
|
69
|
+ See comment near the top of valgrind.h on how to use them.
|
|
70
|
+*/
|
|
71
|
+
|
|
72
|
+#include "valgrind.h"
|
|
73
|
+
|
|
74
|
+/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
|
|
75
|
+ This enum comprises an ABI exported by Valgrind to programs
|
|
76
|
+ which use client requests. DO NOT CHANGE THE ORDER OF THESE
|
|
77
|
+ ENTRIES, NOR DELETE ANY -- add new ones at the end. */
|
|
78
|
+typedef
|
|
79
|
+ enum {
|
|
80
|
+ VG_USERREQ__MAKE_MEM_NOACCESS = VG_USERREQ_TOOL_BASE('M','C'),
|
|
81
|
+ VG_USERREQ__MAKE_MEM_UNDEFINED,
|
|
82
|
+ VG_USERREQ__MAKE_MEM_DEFINED,
|
|
83
|
+ VG_USERREQ__DISCARD,
|
|
84
|
+ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,
|
|
85
|
+ VG_USERREQ__CHECK_MEM_IS_DEFINED,
|
|
86
|
+ VG_USERREQ__DO_LEAK_CHECK,
|
|
87
|
+ VG_USERREQ__COUNT_LEAKS,
|
|
88
|
+
|
|
89
|
+ VG_USERREQ__GET_VBITS,
|
|
90
|
+ VG_USERREQ__SET_VBITS,
|
|
91
|
+
|
|
92
|
+ VG_USERREQ__CREATE_BLOCK,
|
|
93
|
+
|
|
94
|
+ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE,
|
|
95
|
+
|
|
96
|
+ /* Not next to VG_USERREQ__COUNT_LEAKS because it was added later. */
|
|
97
|
+ VG_USERREQ__COUNT_LEAK_BLOCKS,
|
|
98
|
+
|
|
99
|
+ /* This is just for memcheck's internal use - don't use it */
|
|
100
|
+ _VG_USERREQ__MEMCHECK_RECORD_OVERLAP_ERROR
|
|
101
|
+ = VG_USERREQ_TOOL_BASE('M','C') + 256
|
|
102
|
+ } Vg_MemCheckClientRequest;
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+/* Client-code macros to manipulate the state of memory. */
|
|
107
|
+
|
|
108
|
+/* Mark memory at _qzz_addr as unaddressable for _qzz_len bytes. */
|
|
109
|
+#define VALGRIND_MAKE_MEM_NOACCESS(_qzz_addr,_qzz_len) \
|
|
110
|
+ (__extension__({unsigned long _qzz_res; \
|
|
111
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
112
|
+ VG_USERREQ__MAKE_MEM_NOACCESS, \
|
|
113
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
114
|
+ _qzz_res; \
|
|
115
|
+ }))
|
|
116
|
+
|
|
117
|
+/* Similarly, mark memory at _qzz_addr as addressable but undefined
|
|
118
|
+ for _qzz_len bytes. */
|
|
119
|
+#define VALGRIND_MAKE_MEM_UNDEFINED(_qzz_addr,_qzz_len) \
|
|
120
|
+ (__extension__({unsigned long _qzz_res; \
|
|
121
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
122
|
+ VG_USERREQ__MAKE_MEM_UNDEFINED, \
|
|
123
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
124
|
+ _qzz_res; \
|
|
125
|
+ }))
|
|
126
|
+
|
|
127
|
+/* Similarly, mark memory at _qzz_addr as addressable and defined
|
|
128
|
+ for _qzz_len bytes. */
|
|
129
|
+#define VALGRIND_MAKE_MEM_DEFINED(_qzz_addr,_qzz_len) \
|
|
130
|
+ (__extension__({unsigned long _qzz_res; \
|
|
131
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
132
|
+ VG_USERREQ__MAKE_MEM_DEFINED, \
|
|
133
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
134
|
+ _qzz_res; \
|
|
135
|
+ }))
|
|
136
|
+
|
|
137
|
+/* Similar to VALGRIND_MAKE_MEM_DEFINED except that addressability is
|
|
138
|
+ not altered: bytes which are addressable are marked as defined,
|
|
139
|
+ but those which are not addressable are left unchanged. */
|
|
140
|
+#define VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE(_qzz_addr,_qzz_len) \
|
|
141
|
+ (__extension__({unsigned long _qzz_res; \
|
|
142
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
143
|
+ VG_USERREQ__MAKE_MEM_DEFINED_IF_ADDRESSABLE, \
|
|
144
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
145
|
+ _qzz_res; \
|
|
146
|
+ }))
|
|
147
|
+
|
|
148
|
+/* Create a block-description handle. The description is an ascii
|
|
149
|
+ string which is included in any messages pertaining to addresses
|
|
150
|
+ within the specified memory range. Has no other effect on the
|
|
151
|
+ properties of the memory range. */
|
|
152
|
+#define VALGRIND_CREATE_BLOCK(_qzz_addr,_qzz_len, _qzz_desc) \
|
|
153
|
+ (__extension__({unsigned long _qzz_res; \
|
|
154
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
155
|
+ VG_USERREQ__CREATE_BLOCK, \
|
|
156
|
+ _qzz_addr, _qzz_len, _qzz_desc, \
|
|
157
|
+ 0, 0); \
|
|
158
|
+ _qzz_res; \
|
|
159
|
+ }))
|
|
160
|
+
|
|
161
|
+/* Discard a block-description-handle. Returns 1 for an
|
|
162
|
+ invalid handle, 0 for a valid handle. */
|
|
163
|
+#define VALGRIND_DISCARD(_qzz_blkindex) \
|
|
164
|
+ (__extension__ ({unsigned long _qzz_res; \
|
|
165
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* default return */, \
|
|
166
|
+ VG_USERREQ__DISCARD, \
|
|
167
|
+ 0, _qzz_blkindex, 0, 0, 0); \
|
|
168
|
+ _qzz_res; \
|
|
169
|
+ }))
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+/* Client-code macros to check the state of memory. */
|
|
173
|
+
|
|
174
|
+/* Check that memory at _qzz_addr is addressable for _qzz_len bytes.
|
|
175
|
+ If suitable addressibility is not established, Valgrind prints an
|
|
176
|
+ error message and returns the address of the first offending byte.
|
|
177
|
+ Otherwise it returns zero. */
|
|
178
|
+#define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(_qzz_addr,_qzz_len) \
|
|
179
|
+ (__extension__({unsigned long _qzz_res; \
|
|
180
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
181
|
+ VG_USERREQ__CHECK_MEM_IS_ADDRESSABLE,\
|
|
182
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
183
|
+ _qzz_res; \
|
|
184
|
+ }))
|
|
185
|
+
|
|
186
|
+/* Check that memory at _qzz_addr is addressable and defined for
|
|
187
|
+ _qzz_len bytes. If suitable addressibility and definedness are not
|
|
188
|
+ established, Valgrind prints an error message and returns the
|
|
189
|
+ address of the first offending byte. Otherwise it returns zero. */
|
|
190
|
+#define VALGRIND_CHECK_MEM_IS_DEFINED(_qzz_addr,_qzz_len) \
|
|
191
|
+ (__extension__({unsigned long _qzz_res; \
|
|
192
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
193
|
+ VG_USERREQ__CHECK_MEM_IS_DEFINED, \
|
|
194
|
+ _qzz_addr, _qzz_len, 0, 0, 0); \
|
|
195
|
+ _qzz_res; \
|
|
196
|
+ }))
|
|
197
|
+
|
|
198
|
+/* Use this macro to force the definedness and addressibility of an
|
|
199
|
+ lvalue to be checked. If suitable addressibility and definedness
|
|
200
|
+ are not established, Valgrind prints an error message and returns
|
|
201
|
+ the address of the first offending byte. Otherwise it returns
|
|
202
|
+ zero. */
|
|
203
|
+#define VALGRIND_CHECK_VALUE_IS_DEFINED(__lvalue) \
|
|
204
|
+ VALGRIND_CHECK_MEM_IS_DEFINED( \
|
|
205
|
+ (volatile unsigned char *)&(__lvalue), \
|
|
206
|
+ (unsigned long)(sizeof (__lvalue)))
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+/* Do a full memory leak check (like --leak-check=full) mid-execution. */
|
|
210
|
+#define VALGRIND_DO_LEAK_CHECK \
|
|
211
|
+ {unsigned long _qzz_res; \
|
|
212
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
213
|
+ VG_USERREQ__DO_LEAK_CHECK, \
|
|
214
|
+ 0, 0, 0, 0, 0); \
|
|
215
|
+ }
|
|
216
|
+
|
|
217
|
+/* Do a summary memory leak check (like --leak-check=summary) mid-execution. */
|
|
218
|
+#define VALGRIND_DO_QUICK_LEAK_CHECK \
|
|
219
|
+ {unsigned long _qzz_res; \
|
|
220
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
221
|
+ VG_USERREQ__DO_LEAK_CHECK, \
|
|
222
|
+ 1, 0, 0, 0, 0); \
|
|
223
|
+ }
|
|
224
|
+
|
|
225
|
+/* Return number of leaked, dubious, reachable and suppressed bytes found by
|
|
226
|
+ all previous leak checks. They must be lvalues. */
|
|
227
|
+#define VALGRIND_COUNT_LEAKS(leaked, dubious, reachable, suppressed) \
|
|
228
|
+ /* For safety on 64-bit platforms we assign the results to private
|
|
229
|
+ unsigned long variables, then assign these to the lvalues the user
|
|
230
|
+ specified, which works no matter what type 'leaked', 'dubious', etc
|
|
231
|
+ are. We also initialise '_qzz_leaked', etc because
|
|
232
|
+ VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
|
233
|
+ defined. */ \
|
|
234
|
+ {unsigned long _qzz_res; \
|
|
235
|
+ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
|
236
|
+ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
|
237
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
238
|
+ VG_USERREQ__COUNT_LEAKS, \
|
|
239
|
+ &_qzz_leaked, &_qzz_dubious, \
|
|
240
|
+ &_qzz_reachable, &_qzz_suppressed, 0); \
|
|
241
|
+ leaked = _qzz_leaked; \
|
|
242
|
+ dubious = _qzz_dubious; \
|
|
243
|
+ reachable = _qzz_reachable; \
|
|
244
|
+ suppressed = _qzz_suppressed; \
|
|
245
|
+ }
|
|
246
|
+
|
|
247
|
+/* Return number of leaked, dubious, reachable and suppressed bytes found by
|
|
248
|
+ all previous leak checks. They must be lvalues. */
|
|
249
|
+#define VALGRIND_COUNT_LEAK_BLOCKS(leaked, dubious, reachable, suppressed) \
|
|
250
|
+ /* For safety on 64-bit platforms we assign the results to private
|
|
251
|
+ unsigned long variables, then assign these to the lvalues the user
|
|
252
|
+ specified, which works no matter what type 'leaked', 'dubious', etc
|
|
253
|
+ are. We also initialise '_qzz_leaked', etc because
|
|
254
|
+ VG_USERREQ__COUNT_LEAKS doesn't mark the values returned as
|
|
255
|
+ defined. */ \
|
|
256
|
+ {unsigned long _qzz_res; \
|
|
257
|
+ unsigned long _qzz_leaked = 0, _qzz_dubious = 0; \
|
|
258
|
+ unsigned long _qzz_reachable = 0, _qzz_suppressed = 0; \
|
|
259
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
260
|
+ VG_USERREQ__COUNT_LEAK_BLOCKS, \
|
|
261
|
+ &_qzz_leaked, &_qzz_dubious, \
|
|
262
|
+ &_qzz_reachable, &_qzz_suppressed, 0); \
|
|
263
|
+ leaked = _qzz_leaked; \
|
|
264
|
+ dubious = _qzz_dubious; \
|
|
265
|
+ reachable = _qzz_reachable; \
|
|
266
|
+ suppressed = _qzz_suppressed; \
|
|
267
|
+ }
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+/* Get the validity data for addresses [zza..zza+zznbytes-1] and copy it
|
|
271
|
+ into the provided zzvbits array. Return values:
|
|
272
|
+ 0 if not running on valgrind
|
|
273
|
+ 1 success
|
|
274
|
+ 2 [previously indicated unaligned arrays; these are now allowed]
|
|
275
|
+ 3 if any parts of zzsrc/zzvbits are not addressable.
|
|
276
|
+ The metadata is not copied in cases 0, 2 or 3 so it should be
|
|
277
|
+ impossible to segfault your system by using this call.
|
|
278
|
+*/
|
|
279
|
+#define VALGRIND_GET_VBITS(zza,zzvbits,zznbytes) \
|
|
280
|
+ (__extension__({unsigned long _qzz_res; \
|
|
281
|
+ char* czza = (char*)zza; \
|
|
282
|
+ char* czzvbits = (char*)zzvbits; \
|
|
283
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
284
|
+ VG_USERREQ__GET_VBITS, \
|
|
285
|
+ czza, czzvbits, zznbytes, 0, 0 ); \
|
|
286
|
+ _qzz_res; \
|
|
287
|
+ }))
|
|
288
|
+
|
|
289
|
+/* Set the validity data for addresses [zza..zza+zznbytes-1], copying it
|
|
290
|
+ from the provided zzvbits array. Return values:
|
|
291
|
+ 0 if not running on valgrind
|
|
292
|
+ 1 success
|
|
293
|
+ 2 [previously indicated unaligned arrays; these are now allowed]
|
|
294
|
+ 3 if any parts of zza/zzvbits are not addressable.
|
|
295
|
+ The metadata is not copied in cases 0, 2 or 3 so it should be
|
|
296
|
+ impossible to segfault your system by using this call.
|
|
297
|
+*/
|
|
298
|
+#define VALGRIND_SET_VBITS(zza,zzvbits,zznbytes) \
|
|
299
|
+ (__extension__({unsigned int _qzz_res; \
|
|
300
|
+ char* czza = (char*)zza; \
|
|
301
|
+ char* czzvbits = (char*)zzvbits; \
|
|
302
|
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
|
|
303
|
+ VG_USERREQ__SET_VBITS, \
|
|
304
|
+ czza, czzvbits, zznbytes, 0, 0 ); \
|
|
305
|
+ _qzz_res; \
|
|
306
|
+ }))
|
|
307
|
+
|
|
308
|
+#endif
|
|
309
|
+
|