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 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340
|
/*--------------------------------------------------------------------*/
/*--- A header file for all parts of the MemCheck tool. ---*/
/*--- mc_include.h ---*/
/*--------------------------------------------------------------------*/
/*
This file is part of MemCheck, a heavyweight Valgrind tool for
detecting memory errors.
Copyright (C) 2000-2007 Julian Seward
jseward@acm.org
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307, USA.
The GNU General Public License is contained in the file COPYING.
*/
#ifndef __MC_INCLUDE_H
#define __MC_INCLUDE_H
#define MC_(str) VGAPPEND(vgMemCheck_,str)
/*------------------------------------------------------------*/
/*--- Tracking the heap ---*/
/*------------------------------------------------------------*/
/* We want at least a 16B redzone on client heap blocks for Memcheck */
#define MC_MALLOC_REDZONE_SZB 16
/* For malloc()/new/new[] vs. free()/delete/delete[] mismatch checking. */
typedef
enum {
MC_AllocMalloc = 0,
MC_AllocNew = 1,
MC_AllocNewVec = 2,
MC_AllocCustom = 3
}
MC_AllocKind;
/* Nb: first two fields must match core's VgHashNode. */
typedef
struct _MC_Chunk {
struct _MC_Chunk* next;
Addr data; // ptr to actual block
SizeT szB : (sizeof(UWord)*8)-2; // size requested; 30 or 62 bits
MC_AllocKind allockind : 2; // which wrapper did the allocation
ExeContext* where; // where it was allocated
}
MC_Chunk;
/* Memory pool. Nb: first two fields must match core's VgHashNode. */
typedef
struct _MC_Mempool {
struct _MC_Mempool* next;
Addr pool; // pool identifier
SizeT rzB; // pool red-zone size
Bool is_zeroed; // allocations from this pool are zeroed
VgHashTable chunks; // chunks associated with this pool
}
MC_Mempool;
extern void* MC_(new_block) ( ThreadId tid,
Addr p, SizeT size, SizeT align, UInt rzB,
Bool is_zeroed, MC_AllocKind kind,
VgHashTable table);
extern void MC_(handle_free) ( ThreadId tid,
Addr p, UInt rzB, MC_AllocKind kind );
extern void MC_(create_mempool) ( Addr pool, UInt rzB, Bool is_zeroed );
extern void MC_(destroy_mempool) ( Addr pool );
extern void MC_(mempool_alloc) ( ThreadId tid, Addr pool,
Addr addr, SizeT size );
extern void MC_(mempool_free) ( Addr pool, Addr addr );
extern void MC_(mempool_trim) ( Addr pool, Addr addr, SizeT size );
extern void MC_(move_mempool) ( Addr poolA, Addr poolB );
extern void MC_(mempool_change) ( Addr pool, Addr addrA, Addr addrB, SizeT size );
extern Bool MC_(mempool_exists) ( Addr pool );
extern MC_Chunk* MC_(get_freed_list_head)( void );
/* For tracking malloc'd blocks */
extern VgHashTable MC_(malloc_list);
/* For tracking memory pools. */
extern VgHashTable MC_(mempool_list);
/* Shadow memory functions */
extern Bool MC_(check_mem_is_noaccess)( Addr a, SizeT len, Addr* bad_addr );
extern void MC_(make_mem_noaccess) ( Addr a, SizeT len );
extern void MC_(make_mem_undefined)( Addr a, SizeT len );
extern void MC_(make_mem_defined) ( Addr a, SizeT len );
extern void MC_(copy_address_range_state) ( Addr src, Addr dst, SizeT len );
extern void MC_(print_malloc_stats) ( void );
extern void* MC_(malloc) ( ThreadId tid, SizeT n );
extern void* MC_(__builtin_new) ( ThreadId tid, SizeT n );
extern void* MC_(__builtin_vec_new) ( ThreadId tid, SizeT n );
extern void* MC_(memalign) ( ThreadId tid, SizeT align, SizeT n );
extern void* MC_(calloc) ( ThreadId tid, SizeT nmemb, SizeT size1 );
extern void MC_(free) ( ThreadId tid, void* p );
extern void MC_(__builtin_delete) ( ThreadId tid, void* p );
extern void MC_(__builtin_vec_delete) ( ThreadId tid, void* p );
extern void* MC_(realloc) ( ThreadId tid, void* p, SizeT new_size );
/*------------------------------------------------------------*/
/*--- Profiling of memory events ---*/
/*------------------------------------------------------------*/
/* Define to collect detailed performance info. */
/* #define MC_PROFILE_MEMORY */
#ifdef MC_PROFILE_MEMORY
# define N_PROF_EVENTS 500
extern UInt MC_(event_ctr)[N_PROF_EVENTS];
extern HChar* MC_(event_ctr_name)[N_PROF_EVENTS];
# define PROF_EVENT(ev, name) \
do { tl_assert((ev) >= 0 && (ev) < N_PROF_EVENTS); \
/* crude and inaccurate check to ensure the same */ \
/* event isn't being used with > 1 name */ \
if (MC_(event_ctr_name)[ev]) \
tl_assert(name == MC_(event_ctr_name)[ev]); \
MC_(event_ctr)[ev]++; \
MC_(event_ctr_name)[ev] = (name); \
} while (False);
#else
# define PROF_EVENT(ev, name) /* */
#endif /* MC_PROFILE_MEMORY */
/*------------------------------------------------------------*/
/*--- V and A bits (Victoria & Albert ?) ---*/
/*------------------------------------------------------------*/
/* The number of entries in the primary map can be altered. However
we hardwire the assumption that each secondary map covers precisely
64k of address space. */
#define SM_SIZE 65536 /* DO NOT CHANGE */
#define SM_MASK (SM_SIZE-1) /* DO NOT CHANGE */
#define V_BIT_DEFINED 0
#define V_BIT_UNDEFINED 1
#define V_BITS8_DEFINED 0
#define V_BITS8_UNDEFINED 0xFF
#define V_BITS16_DEFINED 0
#define V_BITS16_UNDEFINED 0xFFFF
#define V_BITS32_DEFINED 0
#define V_BITS32_UNDEFINED 0xFFFFFFFF
#define V_BITS64_DEFINED 0ULL
#define V_BITS64_UNDEFINED 0xFFFFFFFFFFFFFFFFULL
/*------------------------------------------------------------*/
/*--- Leak checking ---*/
/*------------------------------------------------------------*/
/* A block is either
-- Proper-ly reached; a pointer to its start has been found
-- Interior-ly reached; only an interior pointer to it has been found
-- Unreached; so far, no pointers to any part of it have been found.
-- IndirectLeak; leaked, but referred to by another leaked block
*/
typedef
enum {
Unreached =0,
IndirectLeak =1,
Interior =2,
Proper =3
}
Reachedness;
/* For VALGRIND_COUNT_LEAKS client request */
extern SizeT MC_(bytes_leaked);
extern SizeT MC_(bytes_indirect);
extern SizeT MC_(bytes_dubious);
extern SizeT MC_(bytes_reachable);
extern SizeT MC_(bytes_suppressed);
typedef
enum {
LC_Off,
LC_Summary,
LC_Full,
}
LeakCheckMode;
/* A block record, used for generating err msgs. */
typedef
struct _LossRecord {
struct _LossRecord* next;
/* Where these lost blocks were allocated. */
ExeContext* allocated_at;
/* Their reachability. */
Reachedness loss_mode;
/* Number of blocks and total # bytes involved. */
SizeT total_bytes;
SizeT indirect_bytes;
UInt num_blocks;
}
LossRecord;
extern void MC_(do_detect_memory_leaks) (
ThreadId tid, LeakCheckMode mode,
Bool (*is_within_valid_secondary) ( Addr ),
Bool (*is_valid_aligned_word) ( Addr )
);
extern void MC_(pp_LeakError)(UInt n_this_record, UInt n_total_records,
LossRecord* l);
/*------------------------------------------------------------*/
/*--- Errors and suppressions ---*/
/*------------------------------------------------------------*/
extern void MC_(record_free_error) ( ThreadId tid, Addr a );
extern void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a );
extern void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc );
extern Bool MC_(record_leak_error) ( ThreadId tid,
UInt n_this_record,
UInt n_total_records,
LossRecord* lossRecord,
Bool print_record );
/*------------------------------------------------------------*/
/*--- Command line options + defaults ---*/
/*------------------------------------------------------------*/
/* Allow loads from partially-valid addresses? default: YES */
extern Bool MC_(clo_partial_loads_ok);
/* Max volume of the freed blocks queue. */
extern Long MC_(clo_freelist_vol);
/* Do leak check at exit? default: NO */
extern LeakCheckMode MC_(clo_leak_check);
/* How closely should we compare ExeContexts in leak records? default: 2 */
extern VgRes MC_(clo_leak_resolution);
/* In leak check, show reachable-but-not-freed blocks? default: NO */
extern Bool MC_(clo_show_reachable);
/* Assume accesses immediately below %esp are due to gcc-2.96 bugs.
* default: NO */
extern Bool MC_(clo_workaround_gcc296_bugs);
/* Do undefined value checking? "No" gives Addrcheck-style behaviour, ie.
* faster but fewer errors found. Note that although Addrcheck had 1 bit
* per byte overhead vs the old Memcheck's 9 bits per byte, with this mode
* and compressed V bits, no memory is saved with this mode -- it's still
* 2 bits per byte overhead. This is a little wasteful -- it could be done
* with 1 bit per byte -- but lets us reuse the many shadow memory access
* functions. Note also that in this mode the secondary V bit table is
* never used.
*
* default: YES */
extern Bool MC_(clo_undef_value_errors);
/* Fill malloc-d/free-d client blocks with a specific value? -1 if
not, else 0x00 .. 0xFF indicating the fill value to use. Can be
useful for causing programs with bad heap corruption to fail in
more repeatable ways. Note that malloc-filled and free-filled
areas are still undefined and noaccess respectively. This merely
causes them to contain the specified values. */
extern Int MC_(clo_malloc_fill);
extern Int MC_(clo_free_fill);
/*------------------------------------------------------------*/
/*--- Instrumentation ---*/
/*------------------------------------------------------------*/
/* Functions defined in mc_main.c */
extern VG_REGPARM(1) void MC_(helperc_complain_undef) ( HWord );
extern void MC_(helperc_value_check8_fail) ( void );
extern void MC_(helperc_value_check4_fail) ( void );
extern void MC_(helperc_value_check1_fail) ( void );
extern void MC_(helperc_value_check0_fail) ( void );
extern VG_REGPARM(1) void MC_(helperc_STOREV64be) ( Addr, ULong );
extern VG_REGPARM(1) void MC_(helperc_STOREV64le) ( Addr, ULong );
extern VG_REGPARM(2) void MC_(helperc_STOREV32be) ( Addr, UWord );
extern VG_REGPARM(2) void MC_(helperc_STOREV32le) ( Addr, UWord );
extern VG_REGPARM(2) void MC_(helperc_STOREV16be) ( Addr, UWord );
extern VG_REGPARM(2) void MC_(helperc_STOREV16le) ( Addr, UWord );
extern VG_REGPARM(2) void MC_(helperc_STOREV8) ( Addr, UWord );
extern VG_REGPARM(1) ULong MC_(helperc_LOADV64be) ( Addr );
extern VG_REGPARM(1) ULong MC_(helperc_LOADV64le) ( Addr );
extern VG_REGPARM(1) UWord MC_(helperc_LOADV32be) ( Addr );
extern VG_REGPARM(1) UWord MC_(helperc_LOADV32le) ( Addr );
extern VG_REGPARM(1) UWord MC_(helperc_LOADV16be) ( Addr );
extern VG_REGPARM(1) UWord MC_(helperc_LOADV16le) ( Addr );
extern VG_REGPARM(1) UWord MC_(helperc_LOADV8) ( Addr );
extern void MC_(helperc_MAKE_STACK_UNINIT) ( Addr base, UWord len );
/* Functions defined in mc_translate.c */
extern
IRSB* MC_(instrument) ( VgCallbackClosure* closure,
IRSB* bb_in,
VexGuestLayout* layout,
VexGuestExtents* vge,
IRType gWordTy, IRType hWordTy );
extern
IRSB* MC_(final_tidy) ( IRSB* );
#endif /* ndef __MC_INCLUDE_H */
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
|