2 /*--------------------------------------------------------------------*/
3 /*--- Management, printing, etc, of errors and suppressions. ---*/
4 /*--- mc_errors.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of MemCheck, a heavyweight Valgrind tool for
9 detecting memory errors.
11 Copyright (C) 2000-2013 Julian Seward
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #include "pub_tool_basics.h"
33 #include "pub_tool_gdbserver.h"
34 #include "pub_tool_poolalloc.h" // For mc_include.h
35 #include "pub_tool_hashtable.h" // For mc_include.h
36 #include "pub_tool_libcbase.h"
37 #include "pub_tool_libcassert.h"
38 #include "pub_tool_libcprint.h"
39 #include "pub_tool_machine.h"
40 #include "pub_tool_mallocfree.h"
41 #include "pub_tool_options.h"
42 #include "pub_tool_replacemalloc.h"
43 #include "pub_tool_tooliface.h"
44 #include "pub_tool_threadstate.h"
45 #include "pub_tool_debuginfo.h" // VG_(get_dataname_and_offset)
46 #include "pub_tool_xarray.h"
47 #include "pub_tool_aspacemgr.h"
48 #include "pub_tool_addrinfo.h"
50 #include "mc_include.h"
53 /*------------------------------------------------------------*/
54 /*--- Error types ---*/
55 /*------------------------------------------------------------*/
57 /* See comment in mc_include.h */
58 Bool
MC_(any_value_errors
) = False
;
61 /* ------------------ Errors ----------------------- */
63 /* What kind of error it is. */
84 typedef struct _MC_Error MC_Error
;
87 // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
91 // Use of an undefined value:
92 // - as a pointer in a load or store
95 SizeT szB
; // size of value in bytes
97 UInt otag
; // origin tag
98 ExeContext
* origin_ec
; // filled in later
101 // Use of an undefined value in a conditional branch or move.
104 UInt otag
; // origin tag
105 ExeContext
* origin_ec
; // filled in later
108 // Addressability error in core (signal-handling) operation.
109 // It would be good to get rid of this error kind, merge it with
110 // another one somehow.
114 // Use of an unaddressable memory location in a load or store.
116 Bool isWrite
; // read or write?
117 SizeT szB
; // not used for exec (jump) errors
118 Bool maybe_gcc
; // True if just below %esp -- could be a gcc bug
122 // Jump to an unaddressable memory location.
127 // System call register input contains undefined bytes.
130 UInt otag
; // origin tag
131 ExeContext
* origin_ec
; // filled in later
134 // System call memory input contains undefined/unaddressable bytes
136 Bool isAddrErr
; // Addressability or definedness error?
139 UInt otag
; // origin tag
140 ExeContext
* origin_ec
; // filled in later
143 // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
145 Bool isAddrErr
; // Addressability or definedness error?
148 UInt otag
; // origin tag
149 ExeContext
* origin_ec
; // filled in later
152 // Program tried to free() something that's not a heap block (this
153 // covers double-frees). */
158 // Program allocates heap block with one function
159 // (malloc/new/new[]/custom) and deallocates with not the matching one.
164 // Call to strcpy, memcpy, etc, with overlapping blocks.
166 Addr src
; // Source block
167 Addr dst
; // Destination block
168 SizeT szB
; // Size in bytes; 0 if unused.
174 UInt n_total_records
;
178 // A memory pool error.
183 // A fishy function argument value
184 // An argument value is considered fishy if the corresponding
185 // parameter has SizeT type and the value when interpreted as a
186 // signed number is negative.
188 const HChar
*function_name
;
189 const HChar
*argument_name
;
196 /*------------------------------------------------------------*/
197 /*--- Printing errors ---*/
198 /*------------------------------------------------------------*/
200 /* This is the "this error is due to be printed shortly; so have a
201 look at it any print any preamble you want" function. Which, in
202 Memcheck, we don't use. Hence a no-op.
204 void MC_(before_pp_Error
) ( const Error
* err
) {
207 /* Do a printf-style operation on either the XML or normal output
208 channel, depending on the setting of VG_(clo_xml).
210 static void emit_WRK ( const HChar
* format
, va_list vargs
)
213 VG_(vprintf_xml
)(format
, vargs
);
215 VG_(vmessage
)(Vg_UserMsg
, format
, vargs
);
218 static void emit ( const HChar
* format
, ... ) PRINTF_CHECK(1, 2);
219 static void emit ( const HChar
* format
, ... )
222 va_start(vargs
, format
);
223 emit_WRK(format
, vargs
);
228 static const HChar
* str_leak_lossmode ( Reachedness lossmode
)
230 const HChar
*loss
= "?";
232 case Unreached
: loss
= "definitely lost"; break;
233 case IndirectLeak
: loss
= "indirectly lost"; break;
234 case Possible
: loss
= "possibly lost"; break;
235 case Reachable
: loss
= "still reachable"; break;
240 static const HChar
* xml_leak_kind ( Reachedness lossmode
)
242 const HChar
*loss
= "?";
244 case Unreached
: loss
= "Leak_DefinitelyLost"; break;
245 case IndirectLeak
: loss
= "Leak_IndirectlyLost"; break;
246 case Possible
: loss
= "Leak_PossiblyLost"; break;
247 case Reachable
: loss
= "Leak_StillReachable"; break;
252 const HChar
* MC_(parse_leak_kinds_tokens
) =
253 "reachable,possible,indirect,definite";
255 UInt
MC_(all_Reachedness
)(void)
260 // Compute a set with all values by doing a parsing of the "all" keyword.
261 Bool parseok
= VG_(parse_enum_set
)(MC_(parse_leak_kinds_tokens
),
265 tl_assert (parseok
&& all
);
271 static const HChar
* pp_Reachedness_for_leak_kinds(Reachedness r
)
274 case Reachable
: return "reachable";
275 case Possible
: return "possible";
276 case IndirectLeak
: return "indirect";
277 case Unreached
: return "definite";
278 default: tl_assert(0);
282 static void mc_pp_origin ( ExeContext
* ec
, UInt okind
)
284 const HChar
* src
= NULL
;
288 case MC_OKIND_STACK
: src
= " by a stack allocation"; break;
289 case MC_OKIND_HEAP
: src
= " by a heap allocation"; break;
290 case MC_OKIND_USER
: src
= " by a client request"; break;
291 case MC_OKIND_UNKNOWN
: src
= ""; break;
293 tl_assert(src
); /* guards against invalid 'okind' */
296 emit( " <auxwhat>Uninitialised value was created%s</auxwhat>\n",
298 VG_(pp_ExeContext
)( ec
);
300 emit( " Uninitialised value was created%s\n", src
);
301 VG_(pp_ExeContext
)( ec
);
305 HChar
* MC_(snprintf_delta
) (HChar
* buf
, Int size
,
306 SizeT current_val
, SizeT old_val
,
307 LeakCheckDeltaMode delta_mode
)
309 // Make sure the buffer size is large enough. With old_val == 0 and
310 // current_val == ULLONG_MAX the delta including inserted commas is:
311 // 18,446,744,073,709,551,615
312 // whose length is 26. Therefore:
313 tl_assert(size
>= 26 + 4 + 1);
315 if (delta_mode
== LCD_Any
)
317 else if (current_val
>= old_val
)
318 VG_(snprintf
) (buf
, size
, " (+%'lu)", current_val
- old_val
);
320 VG_(snprintf
) (buf
, size
, " (-%'lu)", old_val
- current_val
);
325 static void pp_LossRecord(UInt n_this_record
, UInt n_total_records
,
326 LossRecord
* lr
, Bool xml
)
328 // char arrays to produce the indication of increase/decrease in case
329 // of delta_mode != LCD_Any
331 HChar d_direct_bytes
[31];
332 HChar d_indirect_bytes
[31];
333 HChar d_num_blocks
[31];
335 MC_(snprintf_delta
) (d_bytes
, sizeof(d_bytes
),
336 lr
->szB
+ lr
->indirect_szB
,
337 lr
->old_szB
+ lr
->old_indirect_szB
,
338 MC_(detect_memory_leaks_last_delta_mode
));
339 MC_(snprintf_delta
) (d_direct_bytes
, sizeof(d_direct_bytes
),
342 MC_(detect_memory_leaks_last_delta_mode
));
343 MC_(snprintf_delta
) (d_indirect_bytes
, sizeof(d_indirect_bytes
),
345 lr
->old_indirect_szB
,
346 MC_(detect_memory_leaks_last_delta_mode
));
347 MC_(snprintf_delta
) (d_num_blocks
, sizeof(d_num_blocks
),
348 (SizeT
) lr
->num_blocks
,
349 (SizeT
) lr
->old_num_blocks
,
350 MC_(detect_memory_leaks_last_delta_mode
));
353 emit(" <kind>%s</kind>\n", xml_leak_kind(lr
->key
.state
));
354 if (lr
->indirect_szB
> 0) {
355 emit( " <xwhat>\n" );
356 emit( " <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
358 " are %s in loss record %'u of %'u</text>\n",
359 lr
->szB
+ lr
->indirect_szB
, d_bytes
,
360 lr
->szB
, d_direct_bytes
,
361 lr
->indirect_szB
, d_indirect_bytes
,
362 lr
->num_blocks
, d_num_blocks
,
363 str_leak_lossmode(lr
->key
.state
),
364 n_this_record
, n_total_records
);
365 // Nb: don't put commas in these XML numbers
366 emit( " <leakedbytes>%lu</leakedbytes>\n",
367 lr
->szB
+ lr
->indirect_szB
);
368 emit( " <leakedblocks>%u</leakedblocks>\n", lr
->num_blocks
);
369 emit( " </xwhat>\n" );
371 emit( " <xwhat>\n" );
372 emit( " <text>%'lu%s bytes in %'u%s blocks"
373 " are %s in loss record %'u of %'u</text>\n",
374 lr
->szB
, d_direct_bytes
,
375 lr
->num_blocks
, d_num_blocks
,
376 str_leak_lossmode(lr
->key
.state
),
377 n_this_record
, n_total_records
);
378 emit( " <leakedbytes>%ld</leakedbytes>\n", lr
->szB
);
379 emit( " <leakedblocks>%d</leakedblocks>\n", lr
->num_blocks
);
380 emit( " </xwhat>\n" );
382 VG_(pp_ExeContext
)(lr
->key
.allocated_at
);
383 } else { /* ! if (xml) */
384 if (lr
->indirect_szB
> 0) {
386 "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
387 " are %s in loss record %'u of %'u\n",
388 lr
->szB
+ lr
->indirect_szB
, d_bytes
,
389 lr
->szB
, d_direct_bytes
,
390 lr
->indirect_szB
, d_indirect_bytes
,
391 lr
->num_blocks
, d_num_blocks
,
392 str_leak_lossmode(lr
->key
.state
),
393 n_this_record
, n_total_records
397 "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
398 lr
->szB
, d_direct_bytes
,
399 lr
->num_blocks
, d_num_blocks
,
400 str_leak_lossmode(lr
->key
.state
),
401 n_this_record
, n_total_records
404 VG_(pp_ExeContext
)(lr
->key
.allocated_at
);
408 void MC_(pp_LossRecord
)(UInt n_this_record
, UInt n_total_records
,
411 pp_LossRecord (n_this_record
, n_total_records
, l
, /* xml */ False
);
414 void MC_(pp_Error
) ( const Error
* err
)
416 const Bool xml
= VG_(clo_xml
); /* a shorthand */
417 MC_Error
* extra
= VG_(get_error_extra
)(err
);
419 switch (VG_(get_error_kind
)(err
)) {
421 /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
422 /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
423 signal handler frame. --njn */
424 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
425 // the following code is untested. Bad.
427 emit( " <kind>CoreMemError</kind>\n" );
428 emit( " <what>%pS contains unaddressable byte(s)</what>\n",
429 VG_(get_error_string
)(err
));
430 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
432 emit( "%s contains unaddressable byte(s)\n",
433 VG_(get_error_string
)(err
));
434 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
439 MC_(any_value_errors
) = True
;
441 emit( " <kind>UninitValue</kind>\n" );
442 emit( " <what>Use of uninitialised value of size %ld</what>\n",
443 extra
->Err
.Value
.szB
);
444 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
445 if (extra
->Err
.Value
.origin_ec
)
446 mc_pp_origin( extra
->Err
.Value
.origin_ec
,
447 extra
->Err
.Value
.otag
& 3 );
449 /* Could also show extra->Err.Cond.otag if debugging origin
451 emit( "Use of uninitialised value of size %ld\n",
452 extra
->Err
.Value
.szB
);
453 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
454 if (extra
->Err
.Value
.origin_ec
)
455 mc_pp_origin( extra
->Err
.Value
.origin_ec
,
456 extra
->Err
.Value
.otag
& 3 );
461 MC_(any_value_errors
) = True
;
463 emit( " <kind>UninitCondition</kind>\n" );
464 emit( " <what>Conditional jump or move depends"
465 " on uninitialised value(s)</what>\n" );
466 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
467 if (extra
->Err
.Cond
.origin_ec
)
468 mc_pp_origin( extra
->Err
.Cond
.origin_ec
,
469 extra
->Err
.Cond
.otag
& 3 );
471 /* Could also show extra->Err.Cond.otag if debugging origin
473 emit( "Conditional jump or move depends"
474 " on uninitialised value(s)\n" );
475 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
476 if (extra
->Err
.Cond
.origin_ec
)
477 mc_pp_origin( extra
->Err
.Cond
.origin_ec
,
478 extra
->Err
.Cond
.otag
& 3 );
483 MC_(any_value_errors
) = True
;
485 emit( " <kind>SyscallParam</kind>\n" );
486 emit( " <what>Syscall param %pS contains "
487 "uninitialised byte(s)</what>\n",
488 VG_(get_error_string
)(err
) );
489 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
490 if (extra
->Err
.RegParam
.origin_ec
)
491 mc_pp_origin( extra
->Err
.RegParam
.origin_ec
,
492 extra
->Err
.RegParam
.otag
& 3 );
494 emit( "Syscall param %s contains uninitialised byte(s)\n",
495 VG_(get_error_string
)(err
) );
496 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
497 if (extra
->Err
.RegParam
.origin_ec
)
498 mc_pp_origin( extra
->Err
.RegParam
.origin_ec
,
499 extra
->Err
.RegParam
.otag
& 3 );
504 if (!extra
->Err
.MemParam
.isAddrErr
)
505 MC_(any_value_errors
) = True
;
507 emit( " <kind>SyscallParam</kind>\n" );
508 emit( " <what>Syscall param %pS points to %s byte(s)</what>\n",
509 VG_(get_error_string
)(err
),
510 extra
->Err
.MemParam
.isAddrErr
511 ? "unaddressable" : "uninitialised" );
512 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
513 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
),
514 &extra
->Err
.MemParam
.ai
, False
);
515 if (extra
->Err
.MemParam
.origin_ec
516 && !extra
->Err
.MemParam
.isAddrErr
)
517 mc_pp_origin( extra
->Err
.MemParam
.origin_ec
,
518 extra
->Err
.MemParam
.otag
& 3 );
520 emit( "Syscall param %s points to %s byte(s)\n",
521 VG_(get_error_string
)(err
),
522 extra
->Err
.MemParam
.isAddrErr
523 ? "unaddressable" : "uninitialised" );
524 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
525 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
),
526 &extra
->Err
.MemParam
.ai
, False
);
527 if (extra
->Err
.MemParam
.origin_ec
528 && !extra
->Err
.MemParam
.isAddrErr
)
529 mc_pp_origin( extra
->Err
.MemParam
.origin_ec
,
530 extra
->Err
.MemParam
.otag
& 3 );
535 if (!extra
->Err
.User
.isAddrErr
)
536 MC_(any_value_errors
) = True
;
538 emit( " <kind>ClientCheck</kind>\n" );
539 emit( " <what>%s byte(s) found "
540 "during client check request</what>\n",
541 extra
->Err
.User
.isAddrErr
542 ? "Unaddressable" : "Uninitialised" );
543 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
544 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
), &extra
->Err
.User
.ai
,
546 if (extra
->Err
.User
.origin_ec
&& !extra
->Err
.User
.isAddrErr
)
547 mc_pp_origin( extra
->Err
.User
.origin_ec
,
548 extra
->Err
.User
.otag
& 3 );
550 emit( "%s byte(s) found during client check request\n",
551 extra
->Err
.User
.isAddrErr
552 ? "Unaddressable" : "Uninitialised" );
553 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
554 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
), &extra
->Err
.User
.ai
,
556 if (extra
->Err
.User
.origin_ec
&& !extra
->Err
.User
.isAddrErr
)
557 mc_pp_origin( extra
->Err
.User
.origin_ec
,
558 extra
->Err
.User
.otag
& 3 );
564 emit( " <kind>InvalidFree</kind>\n" );
565 emit( " <what>Invalid free() / delete / delete[]"
566 " / realloc()</what>\n" );
567 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
568 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
569 &extra
->Err
.Free
.ai
, False
);
571 emit( "Invalid free() / delete / delete[] / realloc()\n" );
572 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
573 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
574 &extra
->Err
.Free
.ai
, False
);
578 case Err_FreeMismatch
:
580 emit( " <kind>MismatchedFree</kind>\n" );
581 emit( " <what>Mismatched free() / delete / delete []</what>\n" );
582 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
583 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
),
584 &extra
->Err
.FreeMismatch
.ai
, False
);
586 emit( "Mismatched free() / delete / delete []\n" );
587 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
588 VG_(pp_addrinfo_mc
)(VG_(get_error_address
)(err
),
589 &extra
->Err
.FreeMismatch
.ai
, False
);
595 emit( " <kind>Invalid%s</kind>\n",
596 extra
->Err
.Addr
.isWrite
? "Write" : "Read" );
597 emit( " <what>Invalid %s of size %ld</what>\n",
598 extra
->Err
.Addr
.isWrite
? "write" : "read",
599 extra
->Err
.Addr
.szB
);
600 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
601 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
603 extra
->Err
.Addr
.maybe_gcc
);
605 emit( "Invalid %s of size %ld\n",
606 extra
->Err
.Addr
.isWrite
? "write" : "read",
607 extra
->Err
.Addr
.szB
);
608 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
610 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
612 extra
->Err
.Addr
.maybe_gcc
);
618 emit( " <kind>InvalidJump</kind>\n" );
619 emit( " <what>Jump to the invalid address stated "
620 "on the next line</what>\n" );
621 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
622 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
), &extra
->Err
.Jump
.ai
,
625 emit( "Jump to the invalid address stated on the next line\n" );
626 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
627 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
), &extra
->Err
.Jump
.ai
,
634 emit( " <kind>Overlap</kind>\n" );
635 if (extra
->Err
.Overlap
.szB
== 0) {
636 emit( " <what>Source and destination overlap "
637 "in %pS(%#lx, %#lx)\n</what>\n",
638 VG_(get_error_string
)(err
),
639 extra
->Err
.Overlap
.dst
, extra
->Err
.Overlap
.src
);
641 emit( " <what>Source and destination overlap "
642 "in %pS(%#lx, %#lx, %lu)</what>\n",
643 VG_(get_error_string
)(err
),
644 extra
->Err
.Overlap
.dst
, extra
->Err
.Overlap
.src
,
645 extra
->Err
.Overlap
.szB
);
647 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
649 if (extra
->Err
.Overlap
.szB
== 0) {
650 emit( "Source and destination overlap in %s(%#lx, %#lx)\n",
651 VG_(get_error_string
)(err
),
652 extra
->Err
.Overlap
.dst
, extra
->Err
.Overlap
.src
);
654 emit( "Source and destination overlap in %s(%#lx, %#lx, %lu)\n",
655 VG_(get_error_string
)(err
),
656 extra
->Err
.Overlap
.dst
, extra
->Err
.Overlap
.src
,
657 extra
->Err
.Overlap
.szB
);
659 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
663 case Err_IllegalMempool
:
664 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
665 // the following code is untested. Bad.
667 emit( " <kind>InvalidMemPool</kind>\n" );
668 emit( " <what>Illegal memory pool address</what>\n" );
669 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
670 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
671 &extra
->Err
.IllegalMempool
.ai
, False
);
673 emit( "Illegal memory pool address\n" );
674 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
675 VG_(pp_addrinfo_mc
)( VG_(get_error_address
)(err
),
676 &extra
->Err
.IllegalMempool
.ai
, False
);
681 UInt n_this_record
= extra
->Err
.Leak
.n_this_record
;
682 UInt n_total_records
= extra
->Err
.Leak
.n_total_records
;
683 LossRecord
* lr
= extra
->Err
.Leak
.lr
;
684 pp_LossRecord (n_this_record
, n_total_records
, lr
, xml
);
690 emit( " <kind>FishyValue</kind>\n" );
692 emit( "Argument '%s' of function %s has a fishy "
693 "(possibly negative) value: %ld\n",
694 extra
->Err
.FishyValue
.argument_name
,
695 extra
->Err
.FishyValue
.function_name
,
696 (SSizeT
)extra
->Err
.FishyValue
.value
);
698 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
700 emit( "Argument '%s' of function %s has a fishy "
701 "(possibly negative) value: %ld\n",
702 extra
->Err
.FishyValue
.argument_name
,
703 extra
->Err
.FishyValue
.function_name
,
704 (SSizeT
)extra
->Err
.FishyValue
.value
);
705 VG_(pp_ExeContext
)( VG_(get_error_where
)(err
) );
710 VG_(printf
)("Error:\n unknown Memcheck error code %d\n",
711 VG_(get_error_kind
)(err
));
712 VG_(tool_panic
)("unknown error code in mc_pp_Error)");
716 /*------------------------------------------------------------*/
717 /*--- Recording errors ---*/
718 /*------------------------------------------------------------*/
720 /* These many bytes below %ESP are considered addressible if we're
721 doing the --workaround-gcc296-bugs hack. */
722 #define VG_GCC296_BUG_STACK_SLOP 1024
724 /* Is this address within some small distance below %ESP? Used only
725 for the --workaround-gcc296-bugs kludge. */
726 static Bool
is_just_below_ESP( Addr esp
, Addr aa
)
728 esp
-= VG_STACK_REDZONE_SZB
;
729 if (esp
> aa
&& (esp
- aa
) <= VG_GCC296_BUG_STACK_SLOP
)
735 /* --- Called from generated and non-generated code --- */
737 void MC_(record_address_error
) ( ThreadId tid
, Addr a
, Int szB
,
743 if (MC_(in_ignored_range
)(a
))
746 if (VG_(is_watched
)( (isWrite
? write_watchpoint
: read_watchpoint
), a
, szB
))
749 just_below_esp
= is_just_below_ESP( VG_(get_SP
)(tid
), a
);
751 /* If this is caused by an access immediately below %ESP, and the
752 user asks nicely, we just ignore it. */
753 if (MC_(clo_workaround_gcc296_bugs
) && just_below_esp
)
756 extra
.Err
.Addr
.isWrite
= isWrite
;
757 extra
.Err
.Addr
.szB
= szB
;
758 extra
.Err
.Addr
.maybe_gcc
= just_below_esp
;
759 extra
.Err
.Addr
.ai
.tag
= Addr_Undescribed
;
760 VG_(maybe_record_error
)( tid
, Err_Addr
, a
, /*s*/NULL
, &extra
);
763 void MC_(record_value_error
) ( ThreadId tid
, Int szB
, UInt otag
)
766 tl_assert( MC_(clo_mc_level
) >= 2 );
768 tl_assert( MC_(clo_mc_level
) == 3 );
769 extra
.Err
.Value
.szB
= szB
;
770 extra
.Err
.Value
.otag
= otag
;
771 extra
.Err
.Value
.origin_ec
= NULL
; /* Filled in later */
772 VG_(maybe_record_error
)( tid
, Err_Value
, /*addr*/0, /*s*/NULL
, &extra
);
775 void MC_(record_cond_error
) ( ThreadId tid
, UInt otag
)
778 tl_assert( MC_(clo_mc_level
) >= 2 );
780 tl_assert( MC_(clo_mc_level
) == 3 );
781 extra
.Err
.Cond
.otag
= otag
;
782 extra
.Err
.Cond
.origin_ec
= NULL
; /* Filled in later */
783 VG_(maybe_record_error
)( tid
, Err_Cond
, /*addr*/0, /*s*/NULL
, &extra
);
786 /* --- Called from non-generated code --- */
788 /* This is for memory errors in signal-related memory. */
789 void MC_(record_core_mem_error
) ( ThreadId tid
, const HChar
* msg
)
791 VG_(maybe_record_error
)( tid
, Err_CoreMem
, /*addr*/0, msg
, /*extra*/NULL
);
794 void MC_(record_regparam_error
) ( ThreadId tid
, const HChar
* msg
, UInt otag
)
797 tl_assert(VG_INVALID_THREADID
!= tid
);
799 tl_assert( MC_(clo_mc_level
) == 3 );
800 extra
.Err
.RegParam
.otag
= otag
;
801 extra
.Err
.RegParam
.origin_ec
= NULL
; /* Filled in later */
802 VG_(maybe_record_error
)( tid
, Err_RegParam
, /*addr*/0, msg
, &extra
);
805 void MC_(record_memparam_error
) ( ThreadId tid
, Addr a
,
806 Bool isAddrErr
, const HChar
* msg
, UInt otag
)
809 tl_assert(VG_INVALID_THREADID
!= tid
);
811 tl_assert( MC_(clo_mc_level
) >= 2 );
813 tl_assert( MC_(clo_mc_level
) == 3 );
814 tl_assert( !isAddrErr
);
816 extra
.Err
.MemParam
.isAddrErr
= isAddrErr
;
817 extra
.Err
.MemParam
.ai
.tag
= Addr_Undescribed
;
818 extra
.Err
.MemParam
.otag
= otag
;
819 extra
.Err
.MemParam
.origin_ec
= NULL
; /* Filled in later */
820 VG_(maybe_record_error
)( tid
, Err_MemParam
, a
, msg
, &extra
);
823 void MC_(record_jump_error
) ( ThreadId tid
, Addr a
)
826 tl_assert(VG_INVALID_THREADID
!= tid
);
827 extra
.Err
.Jump
.ai
.tag
= Addr_Undescribed
;
828 VG_(maybe_record_error
)( tid
, Err_Jump
, a
, /*s*/NULL
, &extra
);
831 void MC_(record_free_error
) ( ThreadId tid
, Addr a
)
834 tl_assert(VG_INVALID_THREADID
!= tid
);
835 extra
.Err
.Free
.ai
.tag
= Addr_Undescribed
;
836 VG_(maybe_record_error
)( tid
, Err_Free
, a
, /*s*/NULL
, &extra
);
839 void MC_(record_freemismatch_error
) ( ThreadId tid
, MC_Chunk
* mc
)
842 AddrInfo
* ai
= &extra
.Err
.FreeMismatch
.ai
;
843 tl_assert(VG_INVALID_THREADID
!= tid
);
844 ai
->tag
= Addr_Block
;
845 ai
->Addr
.Block
.block_kind
= Block_Mallocd
; // Nb: Not 'Block_Freed'
846 ai
->Addr
.Block
.block_desc
= "block";
847 ai
->Addr
.Block
.block_szB
= mc
->szB
;
848 ai
->Addr
.Block
.rwoffset
= 0;
849 ai
->Addr
.Block
.allocated_at
= MC_(allocated_at
) (mc
);
850 VG_(initThreadInfo
) (&ai
->Addr
.Block
.alloc_tinfo
);
851 ai
->Addr
.Block
.freed_at
= MC_(freed_at
) (mc
);
852 VG_(maybe_record_error
)( tid
, Err_FreeMismatch
, mc
->data
, /*s*/NULL
,
856 void MC_(record_illegal_mempool_error
) ( ThreadId tid
, Addr a
)
859 tl_assert(VG_INVALID_THREADID
!= tid
);
860 extra
.Err
.IllegalMempool
.ai
.tag
= Addr_Undescribed
;
861 VG_(maybe_record_error
)( tid
, Err_IllegalMempool
, a
, /*s*/NULL
, &extra
);
864 void MC_(record_overlap_error
) ( ThreadId tid
, const HChar
* function
,
865 Addr src
, Addr dst
, SizeT szB
)
868 tl_assert(VG_INVALID_THREADID
!= tid
);
869 extra
.Err
.Overlap
.src
= src
;
870 extra
.Err
.Overlap
.dst
= dst
;
871 extra
.Err
.Overlap
.szB
= szB
;
872 VG_(maybe_record_error
)(
873 tid
, Err_Overlap
, /*addr*/0, /*s*/function
, &extra
);
876 Bool
MC_(record_leak_error
) ( ThreadId tid
, UInt n_this_record
,
877 UInt n_total_records
, LossRecord
* lr
,
878 Bool print_record
, Bool count_error
)
881 extra
.Err
.Leak
.n_this_record
= n_this_record
;
882 extra
.Err
.Leak
.n_total_records
= n_total_records
;
883 extra
.Err
.Leak
.lr
= lr
;
885 VG_(unique_error
) ( tid
, Err_Leak
, /*Addr*/0, /*s*/NULL
, &extra
,
886 lr
->key
.allocated_at
, print_record
,
887 /*allow_GDB_attach*/False
, count_error
);
890 Bool
MC_(record_fishy_value_error
) ( ThreadId tid
, const HChar
*function_name
,
891 const HChar
*argument_name
, SizeT value
)
895 tl_assert(VG_INVALID_THREADID
!= tid
);
897 if ((SSizeT
)value
>= 0) return False
; // not a fishy value
899 extra
.Err
.FishyValue
.function_name
= function_name
;
900 extra
.Err
.FishyValue
.argument_name
= argument_name
;
901 extra
.Err
.FishyValue
.value
= value
;
903 VG_(maybe_record_error
)(
904 tid
, Err_FishyValue
, /*addr*/0, /*s*/NULL
, &extra
);
909 void MC_(record_user_error
) ( ThreadId tid
, Addr a
,
910 Bool isAddrErr
, UInt otag
)
914 tl_assert(!isAddrErr
);
915 tl_assert( MC_(clo_mc_level
) == 3 );
918 tl_assert( MC_(clo_mc_level
) >= 2 );
920 tl_assert(VG_INVALID_THREADID
!= tid
);
921 extra
.Err
.User
.isAddrErr
= isAddrErr
;
922 extra
.Err
.User
.ai
.tag
= Addr_Undescribed
;
923 extra
.Err
.User
.otag
= otag
;
924 extra
.Err
.User
.origin_ec
= NULL
; /* Filled in later */
925 VG_(maybe_record_error
)( tid
, Err_User
, a
, /*s*/NULL
, &extra
);
928 /*------------------------------------------------------------*/
929 /*--- Other error operations ---*/
930 /*------------------------------------------------------------*/
932 /* Compare error contexts, to detect duplicates. Note that if they
933 are otherwise the same, the faulting addrs and associated rwoffsets
934 are allowed to be different. */
935 Bool
MC_(eq_Error
) ( VgRes res
, const Error
* e1
, const Error
* e2
)
937 MC_Error
* extra1
= VG_(get_error_extra
)(e1
);
938 MC_Error
* extra2
= VG_(get_error_extra
)(e2
);
940 /* Guaranteed by calling function */
941 tl_assert(VG_(get_error_kind
)(e1
) == VG_(get_error_kind
)(e2
));
943 switch (VG_(get_error_kind
)(e1
)) {
945 const HChar
*e1s
, *e2s
;
946 e1s
= VG_(get_error_string
)(e1
);
947 e2s
= VG_(get_error_string
)(e2
);
948 if (e1s
== e2s
) return True
;
949 if (VG_STREQ(e1s
, e2s
)) return True
;
954 return VG_STREQ(VG_(get_error_string
)(e1
), VG_(get_error_string
)(e2
));
956 // Perhaps we should also check the addrinfo.akinds for equality.
957 // That would result in more error reports, but only in cases where
958 // a register contains uninitialised bytes and points to memory
959 // containing uninitialised bytes. Currently, the 2nd of those to be
960 // detected won't be reported. That is (nearly?) always the memory
961 // error, which is good.
963 if (!VG_STREQ(VG_(get_error_string
)(e1
),
964 VG_(get_error_string
)(e2
))) return False
;
967 return ( extra1
->Err
.User
.isAddrErr
== extra2
->Err
.User
.isAddrErr
971 case Err_FreeMismatch
:
973 case Err_IllegalMempool
:
979 return VG_STREQ(extra1
->Err
.FishyValue
.function_name
,
980 extra2
->Err
.FishyValue
.function_name
) &&
981 VG_STREQ(extra1
->Err
.FishyValue
.argument_name
,
982 extra2
->Err
.FishyValue
.argument_name
);
985 return ( extra1
->Err
.Addr
.szB
== extra2
->Err
.Addr
.szB
989 return ( extra1
->Err
.Value
.szB
== extra2
->Err
.Value
.szB
993 VG_(tool_panic
)("Shouldn't get Err_Leak in mc_eq_Error,\n"
994 "since it's handled with VG_(unique_error)()!");
997 VG_(printf
)("Error:\n unknown error code %d\n",
998 VG_(get_error_kind
)(e1
));
999 VG_(tool_panic
)("unknown error code in mc_eq_Error");
1003 /* Functions used when searching MC_Chunk lists */
1005 Bool
addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk
* mc
, Addr a
)
1007 return VG_(addr_is_in_block
)( a
, mc
->data
, mc
->szB
,
1008 MC_(Malloc_Redzone_SzB
) );
1011 Bool
addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk
* mc
, Addr a
, SizeT rzB
)
1013 return VG_(addr_is_in_block
)( a
, mc
->data
, mc
->szB
,
1017 // Forward declarations
1018 static Bool
client_block_maybe_describe( Addr a
, AddrInfo
* ai
);
1019 static Bool
mempool_block_maybe_describe( Addr a
, AddrInfo
* ai
);
1022 /* Describe an address as best you can, for error messages,
1023 putting the result in ai. */
1024 static void describe_addr ( Addr a
, /*OUT*/AddrInfo
* ai
)
1028 tl_assert(Addr_Undescribed
== ai
->tag
);
1030 /* -- Perhaps it's a user-named block? -- */
1031 if (client_block_maybe_describe( a
, ai
)) {
1034 /* -- Perhaps it's in mempool block? -- */
1035 if (mempool_block_maybe_describe( a
, ai
)) {
1038 /* Blocks allocated by memcheck malloc functions are either
1039 on the recently freed list or on the malloc-ed list.
1040 Custom blocks can be on both : a recently freed block might
1041 have been just re-allocated.
1042 So, first search the malloc-ed block, as the most recent
1043 block is the probable cause of error.
1044 We however detect and report that this is a recently re-allocated
1046 /* -- Search for a currently malloc'd block which might bracket it. -- */
1047 VG_(HT_ResetIter
)(MC_(malloc_list
));
1048 while ( (mc
= VG_(HT_Next
)(MC_(malloc_list
))) ) {
1049 if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc
, a
)) {
1050 ai
->tag
= Addr_Block
;
1051 ai
->Addr
.Block
.block_kind
= Block_Mallocd
;
1052 if (MC_(get_freed_block_bracketting
)( a
))
1053 ai
->Addr
.Block
.block_desc
= "recently re-allocated block";
1055 ai
->Addr
.Block
.block_desc
= "block";
1056 ai
->Addr
.Block
.block_szB
= mc
->szB
;
1057 ai
->Addr
.Block
.rwoffset
= (Word
)a
- (Word
)mc
->data
;
1058 ai
->Addr
.Block
.allocated_at
= MC_(allocated_at
)(mc
);
1059 VG_(initThreadInfo
) (&ai
->Addr
.Block
.alloc_tinfo
);
1060 ai
->Addr
.Block
.freed_at
= MC_(freed_at
)(mc
);
1064 /* -- Search for a recently freed block which might bracket it. -- */
1065 mc
= MC_(get_freed_block_bracketting
)( a
);
1067 ai
->tag
= Addr_Block
;
1068 ai
->Addr
.Block
.block_kind
= Block_Freed
;
1069 ai
->Addr
.Block
.block_desc
= "block";
1070 ai
->Addr
.Block
.block_szB
= mc
->szB
;
1071 ai
->Addr
.Block
.rwoffset
= (Word
)a
- (Word
)mc
->data
;
1072 ai
->Addr
.Block
.allocated_at
= MC_(allocated_at
)(mc
);
1073 VG_(initThreadInfo
) (&ai
->Addr
.Block
.alloc_tinfo
);
1074 ai
->Addr
.Block
.freed_at
= MC_(freed_at
)(mc
);
1078 /* No block found. Search a non-heap block description. */
1079 VG_(describe_addr
) (a
, ai
);
1082 void MC_(pp_describe_addr
) ( Addr a
)
1086 ai
.tag
= Addr_Undescribed
;
1087 describe_addr (a
, &ai
);
1088 VG_(pp_addrinfo_mc
) (a
, &ai
, /* maybe_gcc */ False
);
1089 VG_(clear_addrinfo
) (&ai
);
1092 /* Fill in *origin_ec as specified by otag, or NULL it out if otag
1093 does not refer to a known origin. */
1094 static void update_origin ( /*OUT*/ExeContext
** origin_ec
,
1097 UInt ecu
= otag
& ~3;
1099 if (VG_(is_plausible_ECU
)(ecu
)) {
1100 *origin_ec
= VG_(get_ExeContext_from_ECU
)( ecu
);
1104 /* Updates the copy with address info if necessary (but not for all errors). */
1105 UInt
MC_(update_Error_extra
)( const Error
* err
)
1107 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1109 switch (VG_(get_error_kind
)(err
)) {
1110 // These ones don't have addresses associated with them, and so don't
1111 // need any updating.
1116 case Err_FishyValue
:
1117 // For Err_Leaks the returned size does not matter -- they are always
1118 // shown with VG_(unique_error)() so they 'extra' not copied. But
1119 // we make it consistent with the others.
1121 return sizeof(MC_Error
);
1123 // For value errors, get the ExeContext corresponding to the
1124 // origin tag. Note that it is a kludge to assume that
1125 // a length-1 trace indicates a stack origin. FIXME.
1127 update_origin( &extra
->Err
.Value
.origin_ec
,
1128 extra
->Err
.Value
.otag
);
1129 return sizeof(MC_Error
);
1131 update_origin( &extra
->Err
.Cond
.origin_ec
,
1132 extra
->Err
.Cond
.otag
);
1133 return sizeof(MC_Error
);
1135 update_origin( &extra
->Err
.RegParam
.origin_ec
,
1136 extra
->Err
.RegParam
.otag
);
1137 return sizeof(MC_Error
);
1139 // These ones always involve a memory address.
1141 describe_addr ( VG_(get_error_address
)(err
),
1142 &extra
->Err
.Addr
.ai
);
1143 return sizeof(MC_Error
);
1145 describe_addr ( VG_(get_error_address
)(err
),
1146 &extra
->Err
.MemParam
.ai
);
1147 update_origin( &extra
->Err
.MemParam
.origin_ec
,
1148 extra
->Err
.MemParam
.otag
);
1149 return sizeof(MC_Error
);
1151 describe_addr ( VG_(get_error_address
)(err
),
1152 &extra
->Err
.Jump
.ai
);
1153 return sizeof(MC_Error
);
1155 describe_addr ( VG_(get_error_address
)(err
),
1156 &extra
->Err
.User
.ai
);
1157 update_origin( &extra
->Err
.User
.origin_ec
,
1158 extra
->Err
.User
.otag
);
1159 return sizeof(MC_Error
);
1161 describe_addr ( VG_(get_error_address
)(err
),
1162 &extra
->Err
.Free
.ai
);
1163 return sizeof(MC_Error
);
1164 case Err_IllegalMempool
:
1165 describe_addr ( VG_(get_error_address
)(err
),
1166 &extra
->Err
.IllegalMempool
.ai
);
1167 return sizeof(MC_Error
);
1169 // Err_FreeMismatches have already had their address described; this is
1170 // possible because we have the MC_Chunk on hand when the error is
1171 // detected. However, the address may be part of a user block, and if so
1172 // we override the pre-determined description with a user block one.
1173 case Err_FreeMismatch
: {
1174 tl_assert(extra
&& Block_Mallocd
==
1175 extra
->Err
.FreeMismatch
.ai
.Addr
.Block
.block_kind
);
1176 (void)client_block_maybe_describe( VG_(get_error_address
)(err
),
1177 &extra
->Err
.FreeMismatch
.ai
);
1178 return sizeof(MC_Error
);
1181 default: VG_(tool_panic
)("mc_update_extra: bad errkind");
1186 static Bool
client_block_maybe_describe( Addr a
,
1187 /*OUT*/AddrInfo
* ai
)
1190 CGenBlock
* cgbs
= NULL
;
1193 MC_(get_ClientBlock_array
)( &cgbs
, &cgb_used
);
1195 tl_assert(cgb_used
== 0);
1197 /* Perhaps it's a general block ? */
1198 for (i
= 0; i
< cgb_used
; i
++) {
1199 if (cgbs
[i
].start
== 0 && cgbs
[i
].size
== 0)
1201 // Use zero as the redzone for client blocks.
1202 if (VG_(addr_is_in_block
)(a
, cgbs
[i
].start
, cgbs
[i
].size
, 0)) {
1203 ai
->tag
= Addr_Block
;
1204 ai
->Addr
.Block
.block_kind
= Block_UserG
;
1205 ai
->Addr
.Block
.block_desc
= cgbs
[i
].desc
;
1206 ai
->Addr
.Block
.block_szB
= cgbs
[i
].size
;
1207 ai
->Addr
.Block
.rwoffset
= (Word
)(a
) - (Word
)(cgbs
[i
].start
);
1208 ai
->Addr
.Block
.allocated_at
= cgbs
[i
].where
;
1209 VG_(initThreadInfo
) (&ai
->Addr
.Block
.alloc_tinfo
);
1210 ai
->Addr
.Block
.freed_at
= VG_(null_ExeContext
)();;
1218 static Bool
mempool_block_maybe_describe( Addr a
,
1219 /*OUT*/AddrInfo
* ai
)
1222 tl_assert( MC_(mempool_list
) );
1224 VG_(HT_ResetIter
)( MC_(mempool_list
) );
1225 while ( (mp
= VG_(HT_Next
)(MC_(mempool_list
))) ) {
1226 if (mp
->chunks
!= NULL
) {
1228 VG_(HT_ResetIter
)(mp
->chunks
);
1229 while ( (mc
= VG_(HT_Next
)(mp
->chunks
)) ) {
1230 if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc
, a
, mp
->rzB
)) {
1231 ai
->tag
= Addr_Block
;
1232 ai
->Addr
.Block
.block_kind
= Block_MempoolChunk
;
1233 ai
->Addr
.Block
.block_desc
= "block";
1234 ai
->Addr
.Block
.block_szB
= mc
->szB
;
1235 ai
->Addr
.Block
.rwoffset
= (Word
)a
- (Word
)mc
->data
;
1236 ai
->Addr
.Block
.allocated_at
= MC_(allocated_at
)(mc
);
1237 VG_(initThreadInfo
) (&ai
->Addr
.Block
.alloc_tinfo
);
1238 ai
->Addr
.Block
.freed_at
= MC_(freed_at
)(mc
);
1248 /*------------------------------------------------------------*/
1249 /*--- Suppressions ---*/
1250 /*------------------------------------------------------------*/
1254 ParamSupp
, // Bad syscall params
1255 UserSupp
, // Errors arising from client-request checks
1256 CoreMemSupp
, // Memory errors in core (pthread ops, signal handling)
1258 // Undefined value errors of given size
1259 Value1Supp
, Value2Supp
, Value4Supp
, Value8Supp
, Value16Supp
, Value32Supp
,
1261 // Undefined value error in conditional.
1264 // Unaddressable read/write attempt at given size
1265 Addr1Supp
, Addr2Supp
, Addr4Supp
, Addr8Supp
, Addr16Supp
, Addr32Supp
,
1267 JumpSupp
, // Jump to unaddressable target
1268 FreeSupp
, // Invalid or mismatching free
1269 OverlapSupp
, // Overlapping blocks in memcpy(), strcpy(), etc
1270 LeakSupp
, // Something to be suppressed in a leak check.
1271 MempoolSupp
, // Memory pool suppression.
1272 FishyValueSupp
,// Fishy value suppression.
1276 Bool
MC_(is_recognised_suppression
) ( const HChar
* name
, Supp
* su
)
1280 if (VG_STREQ(name
, "Param")) skind
= ParamSupp
;
1281 else if (VG_STREQ(name
, "User")) skind
= UserSupp
;
1282 else if (VG_STREQ(name
, "CoreMem")) skind
= CoreMemSupp
;
1283 else if (VG_STREQ(name
, "Addr1")) skind
= Addr1Supp
;
1284 else if (VG_STREQ(name
, "Addr2")) skind
= Addr2Supp
;
1285 else if (VG_STREQ(name
, "Addr4")) skind
= Addr4Supp
;
1286 else if (VG_STREQ(name
, "Addr8")) skind
= Addr8Supp
;
1287 else if (VG_STREQ(name
, "Addr16")) skind
= Addr16Supp
;
1288 else if (VG_STREQ(name
, "Addr32")) skind
= Addr32Supp
;
1289 else if (VG_STREQ(name
, "Jump")) skind
= JumpSupp
;
1290 else if (VG_STREQ(name
, "Free")) skind
= FreeSupp
;
1291 else if (VG_STREQ(name
, "Leak")) skind
= LeakSupp
;
1292 else if (VG_STREQ(name
, "Overlap")) skind
= OverlapSupp
;
1293 else if (VG_STREQ(name
, "Mempool")) skind
= MempoolSupp
;
1294 else if (VG_STREQ(name
, "Cond")) skind
= CondSupp
;
1295 else if (VG_STREQ(name
, "Value0")) skind
= CondSupp
; /* backwards compat */
1296 else if (VG_STREQ(name
, "Value1")) skind
= Value1Supp
;
1297 else if (VG_STREQ(name
, "Value2")) skind
= Value2Supp
;
1298 else if (VG_STREQ(name
, "Value4")) skind
= Value4Supp
;
1299 else if (VG_STREQ(name
, "Value8")) skind
= Value8Supp
;
1300 else if (VG_STREQ(name
, "Value16")) skind
= Value16Supp
;
1301 else if (VG_STREQ(name
, "Value32")) skind
= Value32Supp
;
1302 else if (VG_STREQ(name
, "FishyValue")) skind
= FishyValueSupp
;
1306 VG_(set_supp_kind
)(su
, skind
);
1310 typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra
;
1312 struct _MC_LeakSuppExtra
{
1313 UInt match_leak_kinds
;
1315 /* Maintains nr of blocks and bytes suppressed with this suppression
1316 during the leak search identified by leak_search_gen.
1317 blocks_suppressed and bytes_suppressed are reset to 0 when
1318 used the first time during a leak search. */
1319 SizeT blocks_suppressed
;
1320 SizeT bytes_suppressed
;
1321 UInt leak_search_gen
;
1325 const HChar
*function_name
;
1326 const HChar
*argument_name
;
1327 } MC_FishyValueExtra
;
1329 Bool
MC_(read_extra_suppression_info
) ( Int fd
, HChar
** bufpp
,
1330 SizeT
* nBufp
, Int
* lineno
, Supp
*su
)
1335 if (VG_(get_supp_kind
)(su
) == ParamSupp
) {
1336 eof
= VG_(get_line
) ( fd
, bufpp
, nBufp
, lineno
);
1337 if (eof
) return False
;
1338 VG_(set_supp_string
)(su
, VG_(strdup
)("mc.resi.1", *bufpp
));
1339 } else if (VG_(get_supp_kind
)(su
) == LeakSupp
) {
1340 // We might have the optional match-leak-kinds line
1341 MC_LeakSuppExtra
* lse
;
1342 lse
= VG_(malloc
)("mc.resi.2", sizeof(MC_LeakSuppExtra
));
1343 lse
->match_leak_kinds
= MC_(all_Reachedness
)();
1344 lse
->blocks_suppressed
= 0;
1345 lse
->bytes_suppressed
= 0;
1346 lse
->leak_search_gen
= 0;
1347 VG_(set_supp_extra
)(su
, lse
); // By default, all kinds will match.
1348 eof
= VG_(get_line
) ( fd
, bufpp
, nBufp
, lineno
);
1349 if (eof
) return True
; // old LeakSupp style, no match-leak-kinds line.
1350 if (0 == VG_(strncmp
)(*bufpp
, "match-leak-kinds:", 17)) {
1352 while ((*bufpp
)[i
] && VG_(isspace((*bufpp
)[i
])))
1354 if (!VG_(parse_enum_set
)(MC_(parse_leak_kinds_tokens
),
1356 (*bufpp
)+i
, &lse
->match_leak_kinds
)) {
1360 return False
; // unknown extra line.
1362 } else if (VG_(get_supp_kind
)(su
) == FishyValueSupp
) {
1363 MC_FishyValueExtra
*extra
;
1364 HChar
*p
, *function_name
, *argument_name
= NULL
;
1366 eof
= VG_(get_line
) ( fd
, bufpp
, nBufp
, lineno
);
1367 if (eof
) return True
;
1369 // The suppression string is: function_name(argument_name)
1370 function_name
= VG_(strdup
)("mv.resi.4", *bufpp
);
1371 p
= VG_(strchr
)(function_name
, '(');
1375 p
= VG_(strchr
)(p
, ')');
1379 if (p
== NULL
) { // malformed suppression string
1380 VG_(free
)(function_name
);
1384 extra
= VG_(malloc
)("mc.resi.3", sizeof *extra
);
1385 extra
->function_name
= function_name
;
1386 extra
->argument_name
= argument_name
;
1388 VG_(set_supp_extra
)(su
, extra
);
1393 Bool
MC_(error_matches_suppression
) ( const Error
* err
, const Supp
* su
)
1396 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1397 ErrorKind ekind
= VG_(get_error_kind
)(err
);
1399 switch (VG_(get_supp_kind
)(su
)) {
1401 return ((ekind
== Err_RegParam
|| ekind
== Err_MemParam
)
1402 && VG_STREQ(VG_(get_error_string
)(err
),
1403 VG_(get_supp_string
)(su
)));
1406 return (ekind
== Err_User
);
1409 return (ekind
== Err_CoreMem
1410 && VG_STREQ(VG_(get_error_string
)(err
),
1411 VG_(get_supp_string
)(su
)));
1413 case Value1Supp
: su_szB
= 1; goto value_case
;
1414 case Value2Supp
: su_szB
= 2; goto value_case
;
1415 case Value4Supp
: su_szB
= 4; goto value_case
;
1416 case Value8Supp
: su_szB
= 8; goto value_case
;
1417 case Value16Supp
:su_szB
=16; goto value_case
;
1418 case Value32Supp
:su_szB
=32; goto value_case
;
1420 return (ekind
== Err_Value
&& extra
->Err
.Value
.szB
== su_szB
);
1423 return (ekind
== Err_Cond
);
1425 case Addr1Supp
: su_szB
= 1; goto addr_case
;
1426 case Addr2Supp
: su_szB
= 2; goto addr_case
;
1427 case Addr4Supp
: su_szB
= 4; goto addr_case
;
1428 case Addr8Supp
: su_szB
= 8; goto addr_case
;
1429 case Addr16Supp
:su_szB
=16; goto addr_case
;
1430 case Addr32Supp
:su_szB
=32; goto addr_case
;
1432 return (ekind
== Err_Addr
&& extra
->Err
.Addr
.szB
== su_szB
);
1435 return (ekind
== Err_Jump
);
1438 return (ekind
== Err_Free
|| ekind
== Err_FreeMismatch
);
1441 return (ekind
== Err_Overlap
);
1444 if (ekind
== Err_Leak
) {
1445 MC_LeakSuppExtra
* lse
= (MC_LeakSuppExtra
*) VG_(get_supp_extra
)(su
);
1446 if (lse
->leak_search_gen
!= MC_(leak_search_gen
)) {
1447 // First time we see this suppression during this leak search.
1448 // => reset the counters to 0.
1449 lse
->blocks_suppressed
= 0;
1450 lse
->bytes_suppressed
= 0;
1451 lse
->leak_search_gen
= MC_(leak_search_gen
);
1453 return RiS(extra
->Err
.Leak
.lr
->key
.state
, lse
->match_leak_kinds
);
1458 return (ekind
== Err_IllegalMempool
);
1460 case FishyValueSupp
: {
1461 MC_FishyValueExtra
*supp_extra
= VG_(get_supp_extra
)(su
);
1463 return (ekind
== Err_FishyValue
) &&
1464 VG_STREQ(extra
->Err
.FishyValue
.function_name
,
1465 supp_extra
->function_name
) &&
1466 VG_STREQ(extra
->Err
.FishyValue
.argument_name
,
1467 supp_extra
->argument_name
);
1471 VG_(printf
)("Error:\n"
1472 " unknown suppression type %d\n",
1473 VG_(get_supp_kind
)(su
));
1474 VG_(tool_panic
)("unknown suppression type in "
1475 "MC_(error_matches_suppression)");
1479 const HChar
* MC_(get_error_name
) ( const Error
* err
)
1481 switch (VG_(get_error_kind
)(err
)) {
1482 case Err_RegParam
: return "Param";
1483 case Err_MemParam
: return "Param";
1484 case Err_User
: return "User";
1485 case Err_FreeMismatch
: return "Free";
1486 case Err_IllegalMempool
: return "Mempool";
1487 case Err_Free
: return "Free";
1488 case Err_Jump
: return "Jump";
1489 case Err_CoreMem
: return "CoreMem";
1490 case Err_Overlap
: return "Overlap";
1491 case Err_Leak
: return "Leak";
1492 case Err_Cond
: return "Cond";
1493 case Err_FishyValue
: return "FishyValue";
1495 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1496 switch ( extra
->Err
.Addr
.szB
) {
1497 case 1: return "Addr1";
1498 case 2: return "Addr2";
1499 case 4: return "Addr4";
1500 case 8: return "Addr8";
1501 case 16: return "Addr16";
1502 case 32: return "Addr32";
1503 default: VG_(tool_panic
)("unexpected size for Addr");
1507 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1508 switch ( extra
->Err
.Value
.szB
) {
1509 case 1: return "Value1";
1510 case 2: return "Value2";
1511 case 4: return "Value4";
1512 case 8: return "Value8";
1513 case 16: return "Value16";
1514 case 32: return "Value32";
1515 default: VG_(tool_panic
)("unexpected size for Value");
1518 default: VG_(tool_panic
)("get_error_name: unexpected type");
1522 SizeT
MC_(get_extra_suppression_info
) ( const Error
* err
,
1523 /*OUT*/HChar
* buf
, Int nBuf
)
1525 ErrorKind ekind
= VG_(get_error_kind
)(err
);
1527 tl_assert(nBuf
>= 1);
1529 if (Err_RegParam
== ekind
|| Err_MemParam
== ekind
) {
1530 const HChar
* errstr
= VG_(get_error_string
)(err
);
1532 return VG_(snprintf
)(buf
, nBuf
, "%s", errstr
);
1533 } else if (Err_Leak
== ekind
) {
1534 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1535 return VG_(snprintf
) (buf
, nBuf
, "match-leak-kinds: %s",
1536 pp_Reachedness_for_leak_kinds(extra
->Err
.Leak
.lr
->key
.state
));
1537 } else if (Err_FishyValue
== ekind
) {
1538 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1539 return VG_(snprintf
) (buf
, nBuf
, "%s(%s)",
1540 extra
->Err
.FishyValue
.function_name
,
1541 extra
->Err
.FishyValue
.argument_name
);
1548 SizeT
MC_(print_extra_suppression_use
) ( const Supp
*su
,
1549 /*OUT*/HChar
*buf
, Int nBuf
)
1551 tl_assert(nBuf
>= 1);
1553 if (VG_(get_supp_kind
)(su
) == LeakSupp
) {
1554 MC_LeakSuppExtra
*lse
= (MC_LeakSuppExtra
*) VG_(get_supp_extra
) (su
);
1556 if (lse
->leak_search_gen
== MC_(leak_search_gen
)
1557 && lse
->blocks_suppressed
> 0) {
1558 return VG_(snprintf
) (buf
, nBuf
,
1559 "suppressed: %'lu bytes in %'lu blocks",
1560 lse
->bytes_suppressed
,
1561 lse
->blocks_suppressed
);
1569 void MC_(update_extra_suppression_use
) ( const Error
* err
, const Supp
* su
)
1571 if (VG_(get_supp_kind
)(su
) == LeakSupp
) {
1572 MC_LeakSuppExtra
*lse
= (MC_LeakSuppExtra
*) VG_(get_supp_extra
) (su
);
1573 MC_Error
* extra
= VG_(get_error_extra
)(err
);
1575 tl_assert (lse
->leak_search_gen
== MC_(leak_search_gen
));
1576 lse
->blocks_suppressed
+= extra
->Err
.Leak
.lr
->num_blocks
;
1577 lse
->bytes_suppressed
1578 += extra
->Err
.Leak
.lr
->szB
+ extra
->Err
.Leak
.lr
->indirect_szB
;
1582 /*--------------------------------------------------------------------*/
1583 /*--- end mc_errors.c ---*/
1584 /*--------------------------------------------------------------------*/