357
/* An expanding array of AuxMapEnts. */
358
#define N_AUXMAPS 20000 /* HACK */
359
static AuxMapEnt hacky_auxmaps[N_AUXMAPS];
360
static Int auxmap_size = N_AUXMAPS;
361
static Int auxmap_used = 0;
362
static AuxMapEnt* auxmap = &hacky_auxmaps[0];
365
/* Find an entry in the auxiliary map. If an entry is found, move it
366
one step closer to the front of the array, then return its address.
367
If an entry is not found, return NULL. Note carefully that
368
because a each call potentially rearranges the entries, each call
369
to this function invalidates ALL AuxMapEnt*s previously obtained by
372
static AuxMapEnt* maybe_find_in_auxmap ( Addr a )
365
/* Tunable parameter: How big is the L1 queue? */
366
#define N_AUXMAP_L1 24
368
/* Tunable parameter: How far along the L1 queue to insert
369
entries resulting from L2 lookups? */
370
#define AUXMAP_L1_INSERT_IX 12
374
AuxMapEnt* ent; // pointer to the matching auxmap_L2 node
376
auxmap_L1[N_AUXMAP_L1];
378
static OSet* auxmap_L2 = NULL;
380
static void init_auxmap_L1_L2 ( void )
383
for (i = 0; i < N_AUXMAP_L1; i++) {
384
auxmap_L1[i].base = 0;
385
auxmap_L1[i].ent = NULL;
388
tl_assert(0 == offsetof(AuxMapEnt,base));
389
tl_assert(sizeof(Addr) == sizeof(void*));
390
auxmap_L2 = VG_(OSetGen_Create)( /*keyOff*/ offsetof(AuxMapEnt,base),
392
VG_(malloc), VG_(free) );
395
/* Check representation invariants; if OK return NULL; else a
396
descriptive bit of text. Also return the number of
397
non-distinguished secondary maps referred to from the auxiliary
400
static HChar* check_auxmap_L1_L2_sanity ( Word* n_secmaps_found )
403
/* On a 32-bit platform, the L2 and L1 tables should
404
both remain empty forever.
406
On a 64-bit platform:
408
all .base & 0xFFFF == 0
409
all .base > MAX_PRIMARY_ADDRESS
411
all .base & 0xFFFF == 0
412
all (.base > MAX_PRIMARY_ADDRESS
414
and .ent points to an AuxMapEnt with the same .base)
416
(.base == 0 and .ent == NULL)
418
*n_secmaps_found = 0;
419
if (sizeof(void*) == 4) {
420
/* 32-bit platform */
421
if (VG_(OSetGen_Size)(auxmap_L2) != 0)
422
return "32-bit: auxmap_L2 is non-empty";
423
for (i = 0; i < N_AUXMAP_L1; i++)
424
if (auxmap_L1[i].base != 0 || auxmap_L1[i].ent != NULL)
425
return "32-bit: auxmap_L1 is non-empty";
427
/* 64-bit platform */
428
UWord elems_seen = 0;
429
AuxMapEnt *elem, *res;
432
VG_(OSetGen_ResetIter)(auxmap_L2);
433
while ( (elem = VG_(OSetGen_Next)(auxmap_L2)) ) {
435
if (0 != (elem->base & (Addr)0xFFFF))
436
return "64-bit: nonzero .base & 0xFFFF in auxmap_L2";
437
if (elem->base <= MAX_PRIMARY_ADDRESS)
438
return "64-bit: .base <= MAX_PRIMARY_ADDRESS in auxmap_L2";
439
if (elem->sm == NULL)
440
return "64-bit: .sm in _L2 is NULL";
441
if (!is_distinguished_sm(elem->sm))
442
(*n_secmaps_found)++;
444
if (elems_seen != n_auxmap_L2_nodes)
445
return "64-bit: disagreement on number of elems in _L2";
446
/* Check L1-L2 correspondence */
447
for (i = 0; i < N_AUXMAP_L1; i++) {
448
if (auxmap_L1[i].base == 0 && auxmap_L1[i].ent == NULL)
450
if (0 != (auxmap_L1[i].base & (Addr)0xFFFF))
451
return "64-bit: nonzero .base & 0xFFFF in auxmap_L1";
452
if (auxmap_L1[i].base <= MAX_PRIMARY_ADDRESS)
453
return "64-bit: .base <= MAX_PRIMARY_ADDRESS in auxmap_L1";
454
if (auxmap_L1[i].ent == NULL)
455
return "64-bit: .ent is NULL in auxmap_L1";
456
if (auxmap_L1[i].ent->base != auxmap_L1[i].base)
457
return "64-bit: _L1 and _L2 bases are inconsistent";
458
/* Look it up in auxmap_L2. */
459
key.base = auxmap_L1[i].base;
461
res = VG_(OSetGen_Lookup)(auxmap_L2, &key);
463
return "64-bit: _L1 .base not found in _L2";
464
if (res != auxmap_L1[i].ent)
465
return "64-bit: _L1 .ent disagrees with _L2 entry";
467
/* Check L1 contains no duplicates */
468
for (i = 0; i < N_AUXMAP_L1; i++) {
469
if (auxmap_L1[i].base == 0)
471
for (j = i+1; j < N_AUXMAP_L1; j++) {
472
if (auxmap_L1[j].base == 0)
474
if (auxmap_L1[j].base == auxmap_L1[i].base)
475
return "64-bit: duplicate _L1 .base entries";
479
return NULL; /* ok */
482
static void insert_into_auxmap_L1_at ( Word rank, AuxMapEnt* ent )
486
tl_assert(rank >= 0 && rank < N_AUXMAP_L1);
487
for (i = N_AUXMAP_L1-1; i > rank; i--)
488
auxmap_L1[i] = auxmap_L1[i-1];
489
auxmap_L1[rank].base = ent->base;
490
auxmap_L1[rank].ent = ent;
493
static INLINE AuxMapEnt* maybe_find_in_auxmap ( Addr a )
375
499
tl_assert(a > MAX_PRIMARY_ADDRESS);
377
500
a &= ~(Addr)0xFFFF;
381
for (i = 0; i < auxmap_used; i++) {
382
if (auxmap[i].base == a)
502
/* First search the front-cache, which is a self-organising
503
list containing the most popular entries. */
505
if (EXPECTED_TAKEN(auxmap_L1[0].base == a))
506
return auxmap_L1[0].ent;
507
if (EXPECTED_TAKEN(auxmap_L1[1].base == a)) {
508
Addr t_base = auxmap_L1[0].base;
509
AuxMapEnt* t_ent = auxmap_L1[0].ent;
510
auxmap_L1[0].base = auxmap_L1[1].base;
511
auxmap_L1[0].ent = auxmap_L1[1].ent;
512
auxmap_L1[1].base = t_base;
513
auxmap_L1[1].ent = t_ent;
514
return auxmap_L1[0].ent;
517
n_auxmap_L1_searches++;
519
for (i = 0; i < N_AUXMAP_L1; i++) {
520
if (auxmap_L1[i].base == a) {
385
n_auxmap_cmps += (ULong)(i+1);
387
if (i < auxmap_used) {
388
/* Found it. Nudge it a bit closer to the front. */
524
tl_assert(i >= 0 && i <= N_AUXMAP_L1);
526
n_auxmap_L1_cmps += (ULong)(i+1);
528
if (i < N_AUXMAP_L1) {
390
AuxMapEnt tmp = auxmap[i-1];
391
auxmap[i-1] = auxmap[i];
530
Addr t_base = auxmap_L1[i-1].base;
531
AuxMapEnt* t_ent = auxmap_L1[i-1].ent;
532
auxmap_L1[i-1].base = auxmap_L1[i-0].base;
533
auxmap_L1[i-1].ent = auxmap_L1[i-0].ent;
534
auxmap_L1[i-0].base = t_base;
535
auxmap_L1[i-0].ent = t_ent;
538
return auxmap_L1[i].ent;
541
n_auxmap_L2_searches++;
543
/* First see if we already have it. */
547
res = VG_(OSetGen_Lookup)(auxmap_L2, &key);
549
insert_into_auxmap_L1_at( AUXMAP_L1_INSERT_IX, res );
402
/* Find an entry in the auxiliary map. If an entry is found, move it
403
one step closer to the front of the array, then return its address.
404
If an entry is not found, allocate one. Note carefully that
405
because a each call potentially rearranges the entries, each call
406
to this function invalidates ALL AuxMapEnt*s previously obtained by
409
553
static AuxMapEnt* find_or_alloc_in_auxmap ( Addr a )
411
AuxMapEnt* am = maybe_find_in_auxmap(a);
415
/* We didn't find it. Hmm. This is a new piece of address space.
416
We'll need to allocate a new AuxMap entry for it. */
417
if (auxmap_used >= auxmap_size) {
418
tl_assert(auxmap_used == auxmap_size);
419
/* Out of auxmap entries. */
420
tl_assert2(0, "failed to expand the auxmap table");
423
tl_assert(auxmap_used < auxmap_size);
425
auxmap[auxmap_used].base = a & ~(Addr)0xFFFF;
426
auxmap[auxmap_used].sm = &sm_distinguished[SM_DIST_NOACCESS];
429
VG_(printf)("new auxmap, base = 0x%llx\n",
430
(ULong)auxmap[auxmap_used].base );
433
return &auxmap[auxmap_used-1];
555
AuxMapEnt *nyu, *res;
557
/* First see if we already have it. */
558
res = maybe_find_in_auxmap( a );
559
if (EXPECTED_TAKEN(res))
562
/* Ok, there's no entry in the secondary map, so we'll have
566
nyu = (AuxMapEnt*) VG_(OSetGen_AllocNode)( auxmap_L2, sizeof(AuxMapEnt) );
569
nyu->sm = &sm_distinguished[SM_DIST_NOACCESS];
570
VG_(OSetGen_Insert)( auxmap_L2, nyu );
571
insert_into_auxmap_L1_at( AUXMAP_L1_INSERT_IX, nyu );
436
576
/* --------------- SecMap fundamentals --------------- */
870
1010
return bigendian ? (wordszB-1-byteno) : byteno;
1014
/* --------------- Ignored address ranges --------------- */
1016
#define M_IGNORE_RANGES 4
1021
Addr start[M_IGNORE_RANGES];
1022
Addr end[M_IGNORE_RANGES];
1026
static IgnoreRanges ignoreRanges;
1028
static INLINE Bool in_ignored_range ( Addr a )
1031
if (EXPECTED_TAKEN(ignoreRanges.used == 0))
1033
for (i = 0; i < ignoreRanges.used; i++) {
1034
if (a >= ignoreRanges.start[i] && a < ignoreRanges.end[i])
1041
/* Parse a 32- or 64-bit hex number, including leading 0x, from string
1042
starting at *ppc, putting result in *result, and return True. Or
1043
fail, in which case *ppc and *result are undefined, and return
1046
static Bool isHex ( UChar c )
1048
return ((c >= '0' && c <= '9')
1049
|| (c >= 'a' && c <= 'f')
1050
|| (c >= 'A' && c <= 'F'));
1053
static UInt fromHex ( UChar c )
1055
if (c >= '0' && c <= '9')
1056
return (UInt)c - (UInt)'0';
1057
if (c >= 'a' && c <= 'f')
1058
return 10 + (UInt)c - (UInt)'a';
1059
if (c >= 'A' && c <= 'F')
1060
return 10 + (UInt)c - (UInt)'A';
1066
static Bool parse_Addr ( UChar** ppc, Addr* result )
1068
Int used, limit = 2 * sizeof(Addr);
1077
while (isHex(**ppc)) {
1078
UInt d = fromHex(**ppc);
1080
*result = ((*result) << 4) | fromHex(**ppc);
1083
if (used > limit) return False;
1090
/* Parse two such numbers separated by a dash, or fail. */
1092
static Bool parse_range ( UChar** ppc, Addr* result1, Addr* result2 )
1094
Bool ok = parse_Addr(ppc, result1);
1100
ok = parse_Addr(ppc, result2);
1106
/* Parse a set of ranges separated by commas into 'ignoreRanges', or
1109
static Bool parse_ignore_ranges ( UChar* str0 )
1115
ignoreRanges.used = 0;
1117
ok = parse_range(ppc, &start, &end);
1120
if (ignoreRanges.used >= M_IGNORE_RANGES)
1122
ignoreRanges.start[ignoreRanges.used] = start;
1123
ignoreRanges.end[ignoreRanges.used] = end;
1124
ignoreRanges.used++;
873
1136
/* --------------- Load/store slow cases. --------------- */
875
1138
// Forward declarations
876
1139
static void mc_record_address_error ( ThreadId tid, Addr a,
877
1140
Int size, Bool isWrite );
878
static void mc_record_core_mem_error ( ThreadId tid, Bool isUnaddr, Char* s );
879
static void mc_record_param_error ( ThreadId tid, Addr a, Bool isReg,
880
Bool isUnaddr, Char* msg );
1141
static void mc_record_core_mem_error ( ThreadId tid, Bool isAddrErr, Char* s );
1142
static void mc_record_regparam_error ( ThreadId tid, Char* msg );
1143
static void mc_record_memparam_error ( ThreadId tid, Addr a,
1144
Bool isAddrErr, Char* msg );
881
1145
static void mc_record_jump_error ( ThreadId tid, Addr a );
951
1248
PROF_EVENT(35, "mc_STOREVn_slow");
1250
/* ------------ BEGIN semi-fast cases ------------ */
1251
/* These deal quickly-ish with the common auxiliary primary map
1252
cases on 64-bit platforms. Are merely a speedup hack; can be
1253
omitted without loss of correctness/functionality. Note that in
1254
both cases the "sizeof(void*) == 8" causes these cases to be
1255
folded out by compilers on 32-bit platforms. These are derived
1256
from STOREV64 and STOREV32.
1258
if (EXPECTED_TAKEN(sizeof(void*) == 8
1259
&& nBits == 64 && VG_IS_8_ALIGNED(a))) {
1260
SecMap* sm = get_secmap_for_reading(a);
1261
UWord sm_off16 = SM_OFF_16(a);
1262
UWord vabits16 = ((UShort*)(sm->vabits8))[sm_off16];
1263
if (EXPECTED_TAKEN( !is_distinguished_sm(sm) &&
1264
(VA_BITS16_DEFINED == vabits16 ||
1265
VA_BITS16_UNDEFINED == vabits16) )) {
1266
/* Handle common case quickly: a is suitably aligned, */
1267
/* is mapped, and is addressible. */
1268
// Convert full V-bits in register to compact 2-bit form.
1269
if (EXPECTED_TAKEN(V_BITS64_DEFINED == vbytes)) {
1270
((UShort*)(sm->vabits8))[sm_off16] = (UShort)VA_BITS16_DEFINED;
1272
} else if (V_BITS64_UNDEFINED == vbytes) {
1273
((UShort*)(sm->vabits8))[sm_off16] = (UShort)VA_BITS16_UNDEFINED;
1276
/* else fall into the slow case */
1278
/* else fall into the slow case */
1280
if (EXPECTED_TAKEN(sizeof(void*) == 8
1281
&& nBits == 32 && VG_IS_4_ALIGNED(a))) {
1282
SecMap* sm = get_secmap_for_reading(a);
1283
UWord sm_off = SM_OFF(a);
1284
UWord vabits8 = sm->vabits8[sm_off];
1285
if (EXPECTED_TAKEN( !is_distinguished_sm(sm) &&
1286
(VA_BITS8_DEFINED == vabits8 ||
1287
VA_BITS8_UNDEFINED == vabits8) )) {
1288
/* Handle common case quickly: a is suitably aligned, */
1289
/* is mapped, and is addressible. */
1290
// Convert full V-bits in register to compact 2-bit form.
1291
if (EXPECTED_TAKEN(V_BITS32_DEFINED == (vbytes & 0xFFFFFFFF))) {
1292
sm->vabits8[sm_off] = VA_BITS8_DEFINED;
1294
} else if (V_BITS32_UNDEFINED == (vbytes & 0xFFFFFFFF)) {
1295
sm->vabits8[sm_off] = VA_BITS8_UNDEFINED;
1298
/* else fall into the slow case */
1300
/* else fall into the slow case */
1302
/* ------------ END semi-fast cases ------------ */
952
1304
tl_assert(nBits == 64 || nBits == 32 || nBits == 16 || nBits == 8);
954
1306
/* Dump vbytes in memory, iterating from least to most significant
955
byte. At the same time establish addressibility of the
1307
byte. At the same time establish addressibility of the location. */
957
1308
for (i = 0; i < szB; i++) {
958
1309
PROF_EVENT(36, "mc_STOREVn_slow(loop)");
959
1310
ai = a + byte_offset_w(szB, bigendian, i);
2234
mc_record_param_error ( tid, 0, /*isReg*/True, /*isUnaddr*/False, s );
2606
mc_record_regparam_error ( tid, s );
2238
2610
/*------------------------------------------------------------*/
2239
/*--- Error and suppression types ---*/
2611
/*--- Error types ---*/
2240
2612
/*------------------------------------------------------------*/
2614
// Different kinds of blocks.
2616
Block_Mallocd = 111,
2623
/* ------------------ Addresses -------------------- */
2242
2625
/* The classification of a faulting address. */
2245
Undescribed, // as-yet unclassified
2247
Unknown, // classification yielded nothing useful
2249
UserG, // in a user-defined block
2250
Mempool, // in a mempool
2251
Register, // in a register; for Param errors only
2628
Addr_Undescribed, // as-yet unclassified
2629
Addr_Unknown, // classification yielded nothing useful
2255
/* Records info about a faulting address. */
2257
struct { // Used by:
2258
AddrKind akind; // ALL
2259
SizeT blksize; // Freed, Mallocd
2260
OffT rwoffset; // Freed, Mallocd
2261
ExeContext* lastchange; // Freed, Mallocd
2262
ThreadId stack_tid; // Stack
2263
const Char *desc; // UserG
2264
Bool maybe_gcc; // True if just below %esp -- could be a gcc bug.
2270
ParamSupp, // Bad syscall params
2271
CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
2273
// Use of invalid values of given size (MemCheck only)
2274
Value0Supp, Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
2276
// Invalid read/write attempt at given size
2277
Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
2279
FreeSupp, // Invalid or mismatching free
2280
OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
2281
LeakSupp, // Something to be suppressed in a leak check.
2282
MempoolSupp, // Memory pool suppression.
2642
// As-yet unclassified.
2643
struct { } Undescribed;
2647
ThreadId tid; // Which thread's stack?
2650
// This covers heap blocks (normal and from mempools) and user-defined
2653
BlockKind block_kind;
2654
Char* block_desc; // "block", "mempool" or user-defined
2657
ExeContext* lastchange;
2660
// Classification yielded nothing useful.
2666
/* ------------------ Errors ----------------------- */
2286
2668
/* What kind of error it is. */
2289
CoreMemErr, // Error in core op (pthread, signals) or client req
2291
ParamErr, UserErr, /* behaves like an anonymous ParamErr */
2292
FreeErr, FreeMismatchErr,
2299
/* What kind of memory access is involved in the error? */
2301
enum { ReadAxs, WriteAxs, ExecAxs }
2304
/* Extra context for memory errors */
2306
struct { // Used by:
2307
AxsKind axskind; // AddrErr
2308
Int size; // AddrErr, ValueErr
2309
AddrInfo addrinfo; // {Addr,Free,FreeMismatch,Param,User}Err
2310
Bool isUnaddr; // {CoreMem,Param,User}Err
2688
typedef struct _MC_Error MC_Error;
2691
// Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
2695
// Use of an undefined value:
2696
// - as a pointer in a load or store
2697
// - as a jump target
2699
SizeT szB; // size of value in bytes
2702
// Use of an undefined value in a conditional branch or move.
2706
// Addressability error in core (signal-handling) operation.
2707
// It would be good to get rid of this error kind, merge it with
2708
// another one somehow.
2712
// Use of an unaddressable memory location in a load or store.
2714
Bool isWrite; // read or write?
2715
SizeT szB; // not used for exec (jump) errors
2716
Bool maybe_gcc; // True if just below %esp -- could be a gcc bug
2720
// Jump to an unaddressable memory location.
2725
// System call register input contains undefined bytes.
2729
// System call memory input contains undefined/unaddressable bytes
2731
Bool isAddrErr; // Addressability or definedness error?
2735
// Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
2737
Bool isAddrErr; // Addressability or definedness error?
2741
// Program tried to free() something that's not a heap block (this
2742
// covers double-frees). */
2747
// Program allocates heap block with one function
2748
// (malloc/new/new[]/custom) and deallocates with not the matching one.
2753
// Call to strcpy, memcpy, etc, with overlapping blocks.
2755
Addr src; // Source block
2756
Addr dst; // Destination block
2757
Int szB; // Size in bytes; 0 if unused.
2763
UInt n_total_records;
2764
LossRecord* lossRecord;
2767
// A memory pool error.
2314
2776
/*------------------------------------------------------------*/
2315
2777
/*--- Printing errors ---*/
2316
2778
/*------------------------------------------------------------*/
2318
static void mc_pp_AddrInfo ( Addr a, AddrInfo* ai )
2780
static void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
2320
2782
HChar* xpre = VG_(clo_xml) ? " <auxwhat>" : " ";
2321
2783
HChar* xpost = VG_(clo_xml) ? "</auxwhat>" : "";
2323
switch (ai->akind) {
2325
VG_(message)(Vg_UserMsg,
2326
"%sAddress 0x%llx is on thread %d's stack%s",
2327
xpre, (ULong)a, ai->stack_tid, xpost);
2330
if (ai->maybe_gcc) {
2331
2788
VG_(message)(Vg_UserMsg,
2332
2789
"%sAddress 0x%llx is just below the stack ptr. "
2333
2790
"To suppress, use: --workaround-gcc296-bugs=yes%s",
2340
2797
xpre, (ULong)a, xpost);
2343
case Freed: case Mallocd: case UserG: case Mempool: {
2802
VG_(message)(Vg_UserMsg,
2803
"%sAddress 0x%llx is on thread %d's stack%s",
2804
xpre, (ULong)a, ai->Addr.Stack.tid, xpost);
2808
SizeT block_szB = ai->Addr.Block.block_szB;
2809
OffT rwoffset = ai->Addr.Block.rwoffset;
2345
2811
const Char* relative;
2347
if (ai->akind == Mempool) {
2352
if (ai->desc != NULL)
2355
if (ai->rwoffset < 0) {
2356
delta = (SizeT)(- ai->rwoffset);
2814
delta = (SizeT)(-rwoffset);
2357
2815
relative = "before";
2358
} else if (ai->rwoffset >= ai->blksize) {
2359
delta = ai->rwoffset - ai->blksize;
2816
} else if (rwoffset >= block_szB) {
2817
delta = rwoffset - block_szB;
2360
2818
relative = "after";
2362
delta = ai->rwoffset;
2363
2821
relative = "inside";
2365
2823
VG_(message)(Vg_UserMsg,
2366
2824
"%sAddress 0x%lx is %,lu bytes %s a %s of size %,lu %s%s",
2368
a, delta, relative, kind,
2370
ai->akind==Mallocd ? "alloc'd"
2371
: ai->akind==Freed ? "free'd"
2826
a, delta, relative, ai->Addr.Block.block_desc,
2828
ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
2829
: ai->Addr.Block.block_kind==Block_Freed ? "free'd"
2374
VG_(pp_ExeContext)(ai->lastchange);
2832
VG_(pp_ExeContext)(ai->Addr.Block.lastchange);
2382
2837
VG_(tool_panic)("mc_pp_AddrInfo");
2386
static void mc_pp_Error ( Error* err )
2388
MC_Error* err_extra = VG_(get_error_extra)(err);
2841
static const HChar* str_leak_lossmode ( Reachedness lossmode )
2843
const HChar *loss = "?";
2845
case Unreached: loss = "definitely lost"; break;
2846
case IndirectLeak: loss = "indirectly lost"; break;
2847
case Interior: loss = "possibly lost"; break;
2848
case Proper: loss = "still reachable"; break;
2853
static const HChar* xml_leak_kind ( Reachedness lossmode )
2855
const HChar *loss = "?";
2857
case Unreached: loss = "Leak_DefinitelyLost"; break;
2858
case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
2859
case Interior: loss = "Leak_PossiblyLost"; break;
2860
case Proper: loss = "Leak_StillReachable"; break;
2865
static void mc_pp_msg( Char* xml_name, Error* err, const HChar* format, ... )
2390
2867
HChar* xpre = VG_(clo_xml) ? " <what>" : "";
2391
2868
HChar* xpost = VG_(clo_xml) ? "</what>" : "";
2873
VG_(message)(Vg_UserMsg, " <kind>%s</kind>", xml_name);
2874
// Stick xpre and xpost on the front and back of the format string.
2875
VG_(snprintf)(buf, 256, "%s%s%s", xpre, format, xpost);
2876
va_start(vargs, format);
2877
VG_(vmessage) ( Vg_UserMsg, buf, vargs );
2879
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2882
static void mc_pp_Error ( Error* err )
2884
MC_Error* extra = VG_(get_error_extra)(err);
2393
2886
switch (VG_(get_error_kind)(err)) {
2395
Char* s = ( err_extra->isUnaddr ? "unaddressable" : "uninitialised" );
2397
VG_(message)(Vg_UserMsg, " <kind>CoreMemError</kind>");
2398
/* What the hell *is* a CoreMemError? jrs 2005-May-18 */
2399
VG_(message)(Vg_UserMsg, "%s%s contains %s byte(s)%s",
2400
xpre, VG_(get_error_string)(err), s, xpost);
2402
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2888
/* What the hell *is* a CoreMemError? jrs 2005-May-18 */
2889
/* As of 2006-Dec-14, it's caused by unaddressable bytes in a
2890
signal handler frame. --njn */
2891
mc_pp_msg("CoreMemError", err,
2892
"%s contains unaddressable byte(s)",
2893
VG_(get_error_string)(err));
2408
if (err_extra->size == 0) {
2410
VG_(message)(Vg_UserMsg, " <kind>UninitCondition</kind>");
2411
VG_(message)(Vg_UserMsg, "%sConditional jump or move depends"
2412
" on uninitialised value(s)%s",
2898
mc_pp_msg("UninitValue", err,
2899
"Use of uninitialised value of size %d",
2900
extra->Err.Value.szB);
2904
mc_pp_msg("UninitCondition", err,
2905
"Conditional jump or move depends"
2906
" on uninitialised value(s)");
2910
mc_pp_msg("SyscallParam", err,
2911
"Syscall param %s contains uninitialised byte(s)",
2912
VG_(get_error_string)(err));
2916
mc_pp_msg("SyscallParam", err,
2917
"Syscall param %s points to %s byte(s)",
2918
VG_(get_error_string)(err),
2919
( extra->Err.MemParam.isAddrErr
2920
? "unaddressable" : "uninitialised" ));
2921
mc_pp_AddrInfo(VG_(get_error_address)(err),
2922
&extra->Err.MemParam.ai, False);
2926
mc_pp_msg("ClientCheck", err,
2927
"%s byte(s) found during client check request",
2928
( extra->Err.User.isAddrErr
2929
? "Unaddressable" : "Uninitialised" ));
2930
mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
2935
mc_pp_msg("InvalidFree", err,
2936
"Invalid free() / delete / delete[]");
2937
mc_pp_AddrInfo(VG_(get_error_address)(err),
2938
&extra->Err.Free.ai, False);
2941
case Err_FreeMismatch:
2942
mc_pp_msg("MismatchedFree", err,
2943
"Mismatched free() / delete / delete []");
2944
mc_pp_AddrInfo(VG_(get_error_address)(err),
2945
&extra->Err.FreeMismatch.ai, False);
2949
if (extra->Err.Addr.isWrite) {
2950
mc_pp_msg("InvalidWrite", err,
2951
"Invalid write of size %d",
2952
extra->Err.Addr.szB);
2416
VG_(message)(Vg_UserMsg, " <kind>UninitValue</kind>");
2417
VG_(message)(Vg_UserMsg,
2418
"%sUse of uninitialised value of size %d%s",
2419
xpre, err_extra->size, xpost);
2421
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2425
Bool isReg = ( Register == err_extra->addrinfo.akind );
2426
Char* s1 = ( isReg ? "contains" : "points to" );
2427
Char* s2 = ( err_extra->isUnaddr ? "unaddressable" : "uninitialised" );
2428
if (isReg) tl_assert(!err_extra->isUnaddr);
2431
VG_(message)(Vg_UserMsg, " <kind>SyscallParam</kind>");
2432
VG_(message)(Vg_UserMsg, "%sSyscall param %s %s %s byte(s)%s",
2433
xpre, VG_(get_error_string)(err), s1, s2, xpost);
2435
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2436
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2440
Char* s = ( err_extra->isUnaddr ? "Unaddressable" : "Uninitialised" );
2443
VG_(message)(Vg_UserMsg, " <kind>ClientCheck</kind>");
2444
VG_(message)(Vg_UserMsg,
2445
"%s%s byte(s) found during client check request%s",
2448
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2449
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2454
VG_(message)(Vg_UserMsg, " <kind>InvalidFree</kind>");
2455
VG_(message)(Vg_UserMsg,
2456
"%sInvalid free() / delete / delete[]%s",
2458
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2459
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2462
case FreeMismatchErr:
2464
VG_(message)(Vg_UserMsg, " <kind>MismatchedFree</kind>");
2465
VG_(message)(Vg_UserMsg,
2466
"%sMismatched free() / delete / delete []%s",
2468
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2469
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2473
switch (err_extra->axskind) {
2476
VG_(message)(Vg_UserMsg, " <kind>InvalidRead</kind>");
2477
VG_(message)(Vg_UserMsg,
2478
"%sInvalid read of size %d%s",
2479
xpre, err_extra->size, xpost );
2483
VG_(message)(Vg_UserMsg, " <kind>InvalidWrite</kind>");
2484
VG_(message)(Vg_UserMsg,
2485
"%sInvalid write of size %d%s",
2486
xpre, err_extra->size, xpost );
2490
VG_(message)(Vg_UserMsg, " <kind>InvalidJump</kind>");
2491
VG_(message)(Vg_UserMsg,
2492
"%sJump to the invalid address "
2493
"stated on the next line%s",
2497
VG_(tool_panic)("mc_pp_Error(axskind)");
2499
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2500
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2504
OverlapExtra* ov_extra = (OverlapExtra*)VG_(get_error_extra)(err);
2506
VG_(message)(Vg_UserMsg, " <kind>Overlap</kind>");
2507
if (ov_extra->len == -1)
2508
VG_(message)(Vg_UserMsg,
2509
"%sSource and destination overlap in %s(%p, %p)%s",
2511
VG_(get_error_string)(err),
2512
ov_extra->dst, ov_extra->src,
2954
mc_pp_msg("InvalidRead", err,
2955
"Invalid read of size %d",
2956
extra->Err.Addr.szB);
2958
mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.Addr.ai,
2959
extra->Err.Addr.maybe_gcc);
2963
mc_pp_msg("InvalidJump", err,
2964
"Jump to the invalid address stated on the next line");
2965
mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.Jump.ai,
2970
if (extra->Err.Overlap.szB == 0)
2971
mc_pp_msg("Overlap", err,
2972
"Source and destination overlap in %s(%p, %p)",
2973
VG_(get_error_string)(err),
2974
extra->Err.Overlap.dst, extra->Err.Overlap.src);
2515
VG_(message)(Vg_UserMsg,
2516
"%sSource and destination overlap in %s(%p, %p, %d)%s",
2518
VG_(get_error_string)(err),
2519
ov_extra->dst, ov_extra->src, ov_extra->len,
2521
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2525
MC_(pp_LeakError)(err_extra);
2529
case IllegalMempoolErr:
2531
VG_(message)(Vg_UserMsg, " <kind>InvalidMemPool</kind>");
2532
VG_(message)(Vg_UserMsg, "%sIllegal memory pool address%s",
2534
VG_(pp_ExeContext)( VG_(get_error_where)(err) );
2535
mc_pp_AddrInfo(VG_(get_error_address)(err), &err_extra->addrinfo);
2976
mc_pp_msg("Overlap", err,
2977
"Source and destination overlap in %s(%p, %p, %d)",
2978
VG_(get_error_string)(err),
2979
extra->Err.Overlap.dst, extra->Err.Overlap.src,
2980
extra->Err.Overlap.szB);
2983
case Err_IllegalMempool:
2984
mc_pp_msg("InvalidMemPool", err,
2985
"Illegal memory pool address");
2986
mc_pp_AddrInfo(VG_(get_error_address)(err),
2987
&extra->Err.IllegalMempool.ai, False);
2991
HChar* xpre = VG_(clo_xml) ? " <what>" : "";
2992
HChar* xpost = VG_(clo_xml) ? "</what>" : "";
2993
UInt n_this_record = extra->Err.Leak.n_this_record;
2994
UInt n_total_records = extra->Err.Leak.n_total_records;
2995
LossRecord* l = extra->Err.Leak.lossRecord;
2998
VG_(message)(Vg_UserMsg, " <kind>%t</kind>",
2999
xml_leak_kind(l->loss_mode));
3001
VG_(message)(Vg_UserMsg, "");
3004
if (l->indirect_bytes) {
3005
VG_(message)(Vg_UserMsg,
3006
"%s%,lu (%,lu direct, %,lu indirect) bytes in %,u blocks"
3007
" are %s in loss record %,u of %,u%s",
3009
l->total_bytes + l->indirect_bytes,
3010
l->total_bytes, l->indirect_bytes, l->num_blocks,
3011
str_leak_lossmode(l->loss_mode), n_this_record, n_total_records,
3015
// Nb: don't put commas in these XML numbers
3016
VG_(message)(Vg_UserMsg, " <leakedbytes>%lu</leakedbytes>",
3017
l->total_bytes + l->indirect_bytes);
3018
VG_(message)(Vg_UserMsg, " <leakedblocks>%u</leakedblocks>",
3024
"%s%,lu bytes in %,u blocks are %s in loss record %,u of %,u%s",
3026
l->total_bytes, l->num_blocks,
3027
str_leak_lossmode(l->loss_mode), n_this_record, n_total_records,
3031
VG_(message)(Vg_UserMsg, " <leakedbytes>%d</leakedbytes>",
3033
VG_(message)(Vg_UserMsg, " <leakedblocks>%d</leakedblocks>",
3037
VG_(pp_ExeContext)(l->allocated_at);
2539
3042
VG_(printf)("Error:\n unknown Memcheck error code %d\n",
2588
3110
if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
2591
mc_clear_MC_Error( &err_extra );
2592
err_extra.axskind = isWrite ? WriteAxs : ReadAxs;
2593
err_extra.size = size;
2594
err_extra.addrinfo.akind = Undescribed;
2595
err_extra.addrinfo.maybe_gcc = just_below_esp;
2596
VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
2599
/* These ones are called from non-generated code */
3113
extra.Err.Addr.isWrite = isWrite;
3114
extra.Err.Addr.szB = szB;
3115
extra.Err.Addr.maybe_gcc = just_below_esp;
3116
extra.Err.Addr.ai.tag = Addr_Undescribed;
3117
VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
3120
static void mc_record_value_error ( ThreadId tid, Int szB )
3123
tl_assert(MC_(clo_undef_value_errors));
3124
extra.Err.Value.szB = szB;
3125
VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
3128
static void mc_record_cond_error ( ThreadId tid )
3130
tl_assert(MC_(clo_undef_value_errors));
3131
VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, /*extra*/NULL);
3134
/* --- Called from non-generated code --- */
2601
3136
/* This is for memory errors in pthread functions, as opposed to pthread API
2602
3137
errors which are found by the core. */
2603
static void mc_record_core_mem_error ( ThreadId tid, Bool isUnaddr, Char* msg )
2607
mc_clear_MC_Error( &err_extra );
2608
err_extra.isUnaddr = isUnaddr;
2609
VG_(maybe_record_error)( tid, CoreMemErr, /*addr*/0, msg, &err_extra );
2612
// Three kinds of param errors:
2613
// - register arg contains undefined bytes
2614
// - memory arg is unaddressable
2615
// - memory arg contains undefined bytes
2616
// 'isReg' and 'isUnaddr' dictate which of these it is.
2617
static void mc_record_param_error ( ThreadId tid, Addr a, Bool isReg,
2618
Bool isUnaddr, Char* msg )
2622
if (!isUnaddr) tl_assert(MC_(clo_undef_value_errors));
2623
tl_assert(VG_INVALID_THREADID != tid);
2624
if (isUnaddr) tl_assert(!isReg); // unaddressable register is impossible
2625
mc_clear_MC_Error( &err_extra );
2626
err_extra.addrinfo.akind = ( isReg ? Register : Undescribed );
2627
err_extra.isUnaddr = isUnaddr;
2628
VG_(maybe_record_error)( tid, ParamErr, a, msg, &err_extra );
3138
static void mc_record_core_mem_error ( ThreadId tid, Bool isAddrErr, Char* msg )
3140
VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
3143
static void mc_record_regparam_error ( ThreadId tid, Char* msg )
3145
tl_assert(VG_INVALID_THREADID != tid);
3146
VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, /*extra*/NULL );
3149
static void mc_record_memparam_error ( ThreadId tid, Addr a,
3150
Bool isAddrErr, Char* msg )
3153
tl_assert(VG_INVALID_THREADID != tid);
3155
tl_assert(MC_(clo_undef_value_errors));
3156
extra.Err.MemParam.isAddrErr = isAddrErr;
3157
extra.Err.MemParam.ai.tag = Addr_Undescribed;
3158
VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
2631
3161
static void mc_record_jump_error ( ThreadId tid, Addr a )
2635
3164
tl_assert(VG_INVALID_THREADID != tid);
2636
mc_clear_MC_Error( &err_extra );
2637
err_extra.axskind = ExecAxs;
2638
err_extra.size = 1; // size only used for suppressions
2639
err_extra.addrinfo.akind = Undescribed;
2640
VG_(maybe_record_error)( tid, AddrErr, a, /*s*/NULL, &err_extra );
3165
extra.Err.Jump.ai.tag = Addr_Undescribed;
3166
VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
2643
3169
void MC_(record_free_error) ( ThreadId tid, Addr a )
3172
tl_assert(VG_INVALID_THREADID != tid);
3173
extra.Err.Free.ai.tag = Addr_Undescribed;
3174
VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
3177
void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
3180
AddrInfo* ai = &extra.Err.FreeMismatch.ai;
2647
3181
tl_assert(VG_INVALID_THREADID != tid);
2648
mc_clear_MC_Error( &err_extra );
2649
err_extra.addrinfo.akind = Undescribed;
2650
VG_(maybe_record_error)( tid, FreeErr, a, /*s*/NULL, &err_extra );
3182
ai->tag = Addr_Block;
3183
ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed'
3184
ai->Addr.Block.block_desc = "block";
3185
ai->Addr.Block.block_szB = mc->szB;
3186
ai->Addr.Block.rwoffset = 0;
3187
ai->Addr.Block.lastchange = mc->where;
3188
VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
2653
3192
void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
2657
tl_assert(VG_INVALID_THREADID != tid);
2658
mc_clear_MC_Error( &err_extra );
2659
err_extra.addrinfo.akind = Undescribed;
2660
VG_(maybe_record_error)( tid, IllegalMempoolErr, a, /*s*/NULL, &err_extra );
2663
void MC_(record_freemismatch_error) ( ThreadId tid, Addr a, MC_Chunk* mc )
2668
tl_assert(VG_INVALID_THREADID != tid);
2669
mc_clear_MC_Error( &err_extra );
2670
ai = &err_extra.addrinfo;
2671
ai->akind = Mallocd; // Nb: not 'Freed'
2672
ai->blksize = mc->size;
2673
ai->rwoffset = (Int)a - (Int)mc->data;
2674
ai->lastchange = mc->where;
2675
VG_(maybe_record_error)( tid, FreeMismatchErr, a, /*s*/NULL, &err_extra );
2678
static void mc_record_overlap_error ( ThreadId tid,
2679
Char* function, OverlapExtra* ov_extra )
3195
tl_assert(VG_INVALID_THREADID != tid);
3196
extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
3197
VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
3200
static void mc_record_overlap_error ( ThreadId tid, Char* function,
3201
Addr src, Addr dst, SizeT szB )
3204
tl_assert(VG_INVALID_THREADID != tid);
3205
extra.Err.Overlap.src = src;
3206
extra.Err.Overlap.dst = dst;
3207
extra.Err.Overlap.szB = szB;
2681
3208
VG_(maybe_record_error)(
2682
tid, OverlapErr, /*addr*/0, /*s*/function, ov_extra );
3209
tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
2685
Bool MC_(record_leak_error) ( ThreadId tid, /*LeakExtra*/void* leak_extra,
2686
ExeContext* where, Bool print_record )
3212
Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
3213
UInt n_total_records, LossRecord* lossRecord,
3217
extra.Err.Leak.n_this_record = n_this_record;
3218
extra.Err.Leak.n_total_records = n_total_records;
3219
extra.Err.Leak.lossRecord = lossRecord;
2689
VG_(unique_error) ( tid, LeakErr, /*Addr*/0, /*s*/NULL,
2690
/*extra*/leak_extra, where, print_record,
3221
VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
3222
lossRecord->allocated_at, print_record,
2691
3223
/*allow_GDB_attach*/False, /*count_error*/False );
2695
/* Creates a copy of the 'extra' part, updates the copy with address info if
2696
necessary, and returns the copy. */
2697
/* This one called from generated code and non-generated code. */
2698
static void mc_record_value_error ( ThreadId tid, Int size )
2702
tl_assert(MC_(clo_undef_value_errors));
2703
mc_clear_MC_Error( &err_extra );
2704
err_extra.size = size;
2705
err_extra.isUnaddr = False;
2706
VG_(maybe_record_error)( tid, ValueErr, /*addr*/0, /*s*/NULL, &err_extra );
2709
/* This called from non-generated code */
2711
static void mc_record_user_error ( ThreadId tid, Addr a, Bool isWrite,
3226
static void mc_record_user_error ( ThreadId tid, Addr a, Bool isAddrErr )
2716
3230
tl_assert(VG_INVALID_THREADID != tid);
2717
mc_clear_MC_Error( &err_extra );
2718
err_extra.addrinfo.akind = Undescribed;
2719
err_extra.isUnaddr = isUnaddr;
2720
VG_(maybe_record_error)( tid, UserErr, a, /*s*/NULL, &err_extra );
3231
extra.Err.User.isAddrErr = isAddrErr;
3232
extra.Err.User.ai.tag = Addr_Undescribed;
3233
VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
2723
__attribute__ ((unused))
2724
static Bool eq_AddrInfo ( VgRes res, AddrInfo* ai1, AddrInfo* ai2 )
2726
if (ai1->akind != Undescribed
2727
&& ai2->akind != Undescribed
2728
&& ai1->akind != ai2->akind)
2730
if (ai1->akind == Freed || ai1->akind == Mallocd) {
2731
if (ai1->blksize != ai2->blksize)
2733
if (!VG_(eq_ExeContext)(res, ai1->lastchange, ai2->lastchange))
3236
/*------------------------------------------------------------*/
3237
/*--- Other error operations ---*/
3238
/*------------------------------------------------------------*/
2739
3240
/* Compare error contexts, to detect duplicates. Note that if they
2740
3241
are otherwise the same, the faulting addrs and associated rwoffsets
2741
3242
are allowed to be different. */
2742
3243
static Bool mc_eq_Error ( VgRes res, Error* e1, Error* e2 )
2744
MC_Error* e1_extra = VG_(get_error_extra)(e1);
2745
MC_Error* e2_extra = VG_(get_error_extra)(e2);
3245
MC_Error* extra1 = VG_(get_error_extra)(e1);
3246
MC_Error* extra2 = VG_(get_error_extra)(e2);
2747
3248
/* Guaranteed by calling function */
2748
3249
tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
2750
3251
switch (VG_(get_error_kind)(e1)) {
2752
3253
Char *e1s, *e2s;
2753
if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
2754
3254
e1s = VG_(get_error_string)(e1);
2755
3255
e2s = VG_(get_error_string)(e2);
2756
if (e1s == e2s) return True;
2757
if (0 == VG_(strcmp)(e1s, e2s)) return True;
3256
if (e1s == e2s) return True;
3257
if (VG_STREQ(e1s, e2s)) return True;
3262
return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
2761
3264
// Perhaps we should also check the addrinfo.akinds for equality.
2762
3265
// That would result in more error reports, but only in cases where
2763
3266
// a register contains uninitialised bytes and points to memory
2764
3267
// containing uninitialised bytes. Currently, the 2nd of those to be
2765
3268
// detected won't be reported. That is (nearly?) always the memory
2766
3269
// error, which is good.
2768
if (0 != VG_(strcmp)(VG_(get_error_string)(e1),
2769
VG_(get_error_string)(e2))) return False;
3271
if (!VG_STREQ(VG_(get_error_string)(e1),
3272
VG_(get_error_string)(e2))) return False;
2770
3273
// fall through
2772
if (e1_extra->isUnaddr != e2_extra->isUnaddr) return False;
2776
case FreeMismatchErr:
2777
/* JRS 2002-Aug-26: comparing addrs seems overkill and can
2778
cause excessive duplication of errors. Not even AddrErr
2779
below does that. So don't compare either the .addr field
2780
or the .addrinfo fields. */
2781
/* if (e1->addr != e2->addr) return False; */
2782
/* if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
2788
/* if (e1_extra->axskind != e2_extra->axskind) return False; */
2789
if (e1_extra->size != e2_extra->size) return False;
2791
if (!eq_AddrInfo(res, &e1_extra->addrinfo, &e2_extra->addrinfo))
2797
if (e1_extra->size != e2_extra->size) return False;
2804
VG_(tool_panic)("Shouldn't get LeakErr in mc_eq_Error,\n"
3275
return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
3279
case Err_FreeMismatch:
3281
case Err_IllegalMempool:
3287
return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
3291
return ( extra1->Err.Value.szB == extra2->Err.Value.szB
3295
VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
2805
3296
"since it's handled with VG_(unique_error)()!");
2807
case IllegalMempoolErr:
2811
3299
VG_(printf)("Error:\n unknown error code %d\n",
2812
3300
VG_(get_error_kind)(e1));
2867
3360
VG_(HT_ResetIter)(MC_(malloc_list));
2868
3361
while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
2869
3362
if (addr_is_in_MC_Chunk(mc, a)) {
2870
ai->akind = Mallocd;
2871
ai->blksize = mc->size;
2872
ai->rwoffset = (Int)(a) - (Int)mc->data;
2873
ai->lastchange = mc->where;
3363
ai->tag = Addr_Block;
3364
ai->Addr.Block.block_kind = Block_Mallocd;
3365
ai->Addr.Block.block_desc = "block";
3366
ai->Addr.Block.block_szB = mc->szB;
3367
ai->Addr.Block.rwoffset = (Int)a - (Int)mc->data;
3368
ai->Addr.Block.lastchange = mc->where;
2877
3372
/* Clueless ... */
2878
ai->akind = Unknown;
3373
ai->tag = Addr_Unknown;
2882
3377
/* Updates the copy with address info if necessary (but not for all errors). */
2883
3378
static UInt mc_update_extra( Error* err )
3380
MC_Error* extra = VG_(get_error_extra)(err);
2885
3382
switch (VG_(get_error_kind)(err)) {
2886
// These two don't have addresses associated with them, and so don't
3383
// These ones don't have addresses associated with them, and so don't
2887
3384
// need any updating.
2890
MC_Error* extra = VG_(get_error_extra)(err);
2891
tl_assert(Unknown == extra->addrinfo.akind);
2892
return sizeof(MC_Error);
2895
// ParamErrs sometimes involve a memory address; call describe_addr() in
2898
MC_Error* extra = VG_(get_error_extra)(err);
2899
tl_assert(Undescribed == extra->addrinfo.akind ||
2900
Register == extra->addrinfo.akind);
2901
if (Undescribed == extra->addrinfo.akind)
2902
describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
2903
return sizeof(MC_Error);
2906
// These four always involve a memory address.
2910
case IllegalMempoolErr: {
2911
MC_Error* extra = VG_(get_error_extra)(err);
2912
tl_assert(Undescribed == extra->addrinfo.akind);
2913
describe_addr ( VG_(get_error_address)(err), &(extra->addrinfo) );
2914
return sizeof(MC_Error);
2917
// FreeMismatchErrs have already had their address described; this is
3390
// For Err_Leaks the returned size does not matter -- they are always
3391
// shown with VG_(unique_error)() so they 'extra' not copied. But we make it
3392
// consistent with the others.
3394
return sizeof(MC_Error);
3396
// These ones always involve a memory address.
3398
describe_addr ( VG_(get_error_address)(err), &extra->Err.Addr.ai );
3399
return sizeof(MC_Error);
3401
describe_addr ( VG_(get_error_address)(err), &extra->Err.MemParam.ai );
3402
return sizeof(MC_Error);
3404
describe_addr ( VG_(get_error_address)(err), &extra->Err.Jump.ai );
3405
return sizeof(MC_Error);
3407
describe_addr ( VG_(get_error_address)(err), &extra->Err.User.ai );
3408
return sizeof(MC_Error);
3410
describe_addr ( VG_(get_error_address)(err), &extra->Err.Free.ai );
3411
return sizeof(MC_Error);
3412
case Err_IllegalMempool:
3413
describe_addr ( VG_(get_error_address)(err),
3414
&extra->Err.IllegalMempool.ai );
3415
return sizeof(MC_Error);
3417
// Err_FreeMismatches have already had their address described; this is
2918
3418
// possible because we have the MC_Chunk on hand when the error is
2919
3419
// detected. However, the address may be part of a user block, and if so
2920
3420
// we override the pre-determined description with a user block one.
2921
case FreeMismatchErr: {
2922
MC_Error* extra = VG_(get_error_extra)(err);
2923
tl_assert(extra && Mallocd == extra->addrinfo.akind);
3421
case Err_FreeMismatch: {
3422
tl_assert(extra && Block_Mallocd ==
3423
extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
2924
3424
(void)client_perm_maybe_describe( VG_(get_error_address)(err),
2925
&(extra->addrinfo) );
3425
&extra->Err.FreeMismatch.ai );
2926
3426
return sizeof(MC_Error);
2929
// No memory address involved with these ones. Nb: for LeakErrs the
2930
// returned size does not matter -- LeakErrs are always shown with
2931
// VG_(unique_error)() so they're not copied.
2932
case LeakErr: return 0;
2933
case OverlapErr: return sizeof(OverlapExtra);
2935
3429
default: VG_(tool_panic)("mc_update_extra: bad errkind");
2940
3434
/*--- Suppressions ---*/
2941
3435
/*------------------------------------------------------------*/
3439
ParamSupp, // Bad syscall params
3440
UserSupp, // Errors arising from client-request checks
3441
CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
3443
// Undefined value errors of given size
3444
Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
3446
// Undefined value error in conditional.
3449
// Unaddressable read/write attempt at given size
3450
Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
3452
JumpSupp, // Jump to unaddressable target
3453
FreeSupp, // Invalid or mismatching free
3454
OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
3455
LeakSupp, // Something to be suppressed in a leak check.
3456
MempoolSupp, // Memory pool suppression.
2943
3460
static Bool mc_recognised_suppression ( Char* name, Supp* su )
2945
3462
SuppKind skind;
2947
3464
if (VG_STREQ(name, "Param")) skind = ParamSupp;
3465
else if (VG_STREQ(name, "User")) skind = UserSupp;
2948
3466
else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
2949
3467
else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
2950
3468
else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
2951
3469
else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
2952
3470
else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
2953
3471
else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
3472
else if (VG_STREQ(name, "Jump")) skind = JumpSupp;
2954
3473
else if (VG_STREQ(name, "Free")) skind = FreeSupp;
2955
3474
else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
2956
3475
else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
2957
3476
else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
2958
else if (VG_STREQ(name, "Cond")) skind = Value0Supp;
2959
else if (VG_STREQ(name, "Value0")) skind = Value0Supp;/* backwards compat */
3477
else if (VG_STREQ(name, "Cond")) skind = CondSupp;
3478
else if (VG_STREQ(name, "Value0")) skind = CondSupp; /* backwards compat */
2960
3479
else if (VG_STREQ(name, "Value1")) skind = Value1Supp;
2961
3480
else if (VG_STREQ(name, "Value2")) skind = Value2Supp;
2962
3481
else if (VG_STREQ(name, "Value4")) skind = Value4Supp;
2985
3504
static Bool mc_error_matches_suppression(Error* err, Supp* su)
2988
MC_Error* err_extra = VG_(get_error_extra)(err);
2989
ErrorKind ekind = VG_(get_error_kind )(err);
3507
MC_Error* extra = VG_(get_error_extra)(err);
3508
ErrorKind ekind = VG_(get_error_kind )(err);
2991
3510
switch (VG_(get_supp_kind)(su)) {
2992
3511
case ParamSupp:
2993
return (ekind == ParamErr
3512
return ((ekind == Err_RegParam || ekind == Err_MemParam)
2994
3513
&& VG_STREQ(VG_(get_error_string)(err),
2995
3514
VG_(get_supp_string)(su)));
3517
return (ekind == Err_User);
2997
3519
case CoreMemSupp:
2998
return (ekind == CoreMemErr
3520
return (ekind == Err_CoreMem
2999
3521
&& VG_STREQ(VG_(get_error_string)(err),
3000
3522
VG_(get_supp_string)(su)));
3002
case Value0Supp: su_size = 0; goto value_case;
3003
case Value1Supp: su_size = 1; goto value_case;
3004
case Value2Supp: su_size = 2; goto value_case;
3005
case Value4Supp: su_size = 4; goto value_case;
3006
case Value8Supp: su_size = 8; goto value_case;
3007
case Value16Supp:su_size =16; goto value_case;
3524
case Value1Supp: su_szB = 1; goto value_case;
3525
case Value2Supp: su_szB = 2; goto value_case;
3526
case Value4Supp: su_szB = 4; goto value_case;
3527
case Value8Supp: su_szB = 8; goto value_case;
3528
case Value16Supp:su_szB =16; goto value_case;
3009
return (ekind == ValueErr && err_extra->size == su_size);
3011
case Addr1Supp: su_size = 1; goto addr_case;
3012
case Addr2Supp: su_size = 2; goto addr_case;
3013
case Addr4Supp: su_size = 4; goto addr_case;
3014
case Addr8Supp: su_size = 8; goto addr_case;
3015
case Addr16Supp:su_size =16; goto addr_case;
3530
return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
3533
return (ekind == Err_Cond);
3535
case Addr1Supp: su_szB = 1; goto addr_case;
3536
case Addr2Supp: su_szB = 2; goto addr_case;
3537
case Addr4Supp: su_szB = 4; goto addr_case;
3538
case Addr8Supp: su_szB = 8; goto addr_case;
3539
case Addr16Supp:su_szB =16; goto addr_case;
3017
return (ekind == AddrErr && err_extra->size == su_size);
3541
return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
3544
return (ekind == Err_Jump);
3020
return (ekind == FreeErr || ekind == FreeMismatchErr);
3547
return (ekind == Err_Free || ekind == Err_FreeMismatch);
3022
3549
case OverlapSupp:
3023
return (ekind = OverlapErr);
3550
return (ekind == Err_Overlap);
3026
return (ekind == LeakErr);
3553
return (ekind == Err_Leak);
3028
3555
case MempoolSupp:
3029
return (ekind == IllegalMempoolErr);
3556
return (ekind == Err_IllegalMempool);
3032
3559
VG_(printf)("Error:\n"