blob: 739034849ea3988ff74027066666e708f1f019b5 [file] [log] [blame]
sewardj7ce71662008-05-02 10:33:15 +00001
2/*--------------------------------------------------------------------*/
3/*--- Management, printing, etc, of errors and suppressions. ---*/
4/*--- mc_errors.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of MemCheck, a heavyweight Valgrind tool for
9 detecting memory errors.
10
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright (C) 2000-2017 Julian Seward
sewardj7ce71662008-05-02 10:33:15 +000012 jseward@acm.org
13
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.
18
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.
23
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
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#include "pub_tool_basics.h"
sewardj3b290482011-05-06 21:02:55 +000033#include "pub_tool_gdbserver.h"
philippe6643e962012-01-17 21:16:30 +000034#include "pub_tool_poolalloc.h" // For mc_include.h
sewardj7ce71662008-05-02 10:33:15 +000035#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"
sewardj7ce71662008-05-02 10:33:15 +000042#include "pub_tool_replacemalloc.h"
43#include "pub_tool_tooliface.h"
44#include "pub_tool_threadstate.h"
sewardj7ce71662008-05-02 10:33:15 +000045#include "pub_tool_debuginfo.h" // VG_(get_dataname_and_offset)
sewardj6b523cd2009-07-15 14:49:40 +000046#include "pub_tool_xarray.h"
philippef7ec77f2014-11-24 17:46:41 +000047#include "pub_tool_aspacemgr.h"
philippe07c08522014-05-14 20:39:27 +000048#include "pub_tool_addrinfo.h"
sewardj7ce71662008-05-02 10:33:15 +000049
50#include "mc_include.h"
sewardj7ce71662008-05-02 10:33:15 +000051
52
53/*------------------------------------------------------------*/
54/*--- Error types ---*/
55/*------------------------------------------------------------*/
56
57/* See comment in mc_include.h */
58Bool MC_(any_value_errors) = False;
59
60
sewardj7ce71662008-05-02 10:33:15 +000061/* ------------------ Errors ----------------------- */
62
63/* What kind of error it is. */
64typedef
65 enum {
66 Err_Value,
67 Err_Cond,
68 Err_CoreMem,
69 Err_Addr,
70 Err_Jump,
71 Err_RegParam,
72 Err_MemParam,
73 Err_User,
74 Err_Free,
75 Err_FreeMismatch,
76 Err_Overlap,
77 Err_Leak,
78 Err_IllegalMempool,
florian7b6899d2014-07-13 14:41:55 +000079 Err_FishyValue,
sewardj7ce71662008-05-02 10:33:15 +000080 }
81 MC_ErrorTag;
82
83
84typedef struct _MC_Error MC_Error;
85
86struct _MC_Error {
87 // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
88 //MC_ErrorTag tag;
89
90 union {
91 // Use of an undefined value:
92 // - as a pointer in a load or store
93 // - as a jump target
94 struct {
95 SizeT szB; // size of value in bytes
96 // Origin info
97 UInt otag; // origin tag
98 ExeContext* origin_ec; // filled in later
99 } Value;
100
101 // Use of an undefined value in a conditional branch or move.
102 struct {
103 // Origin info
104 UInt otag; // origin tag
105 ExeContext* origin_ec; // filled in later
106 } Cond;
107
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.
111 struct {
112 } CoreMem;
113
114 // Use of an unaddressable memory location in a load or store.
115 struct {
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
119 AddrInfo ai;
120 } Addr;
121
122 // Jump to an unaddressable memory location.
123 struct {
124 AddrInfo ai;
125 } Jump;
126
127 // System call register input contains undefined bytes.
128 struct {
129 // Origin info
130 UInt otag; // origin tag
131 ExeContext* origin_ec; // filled in later
132 } RegParam;
133
134 // System call memory input contains undefined/unaddressable bytes
135 struct {
136 Bool isAddrErr; // Addressability or definedness error?
137 AddrInfo ai;
138 // Origin info
139 UInt otag; // origin tag
140 ExeContext* origin_ec; // filled in later
141 } MemParam;
142
143 // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
144 struct {
145 Bool isAddrErr; // Addressability or definedness error?
146 AddrInfo ai;
147 // Origin info
148 UInt otag; // origin tag
149 ExeContext* origin_ec; // filled in later
150 } User;
151
152 // Program tried to free() something that's not a heap block (this
153 // covers double-frees). */
154 struct {
155 AddrInfo ai;
156 } Free;
157
158 // Program allocates heap block with one function
159 // (malloc/new/new[]/custom) and deallocates with not the matching one.
160 struct {
161 AddrInfo ai;
162 } FreeMismatch;
163
164 // Call to strcpy, memcpy, etc, with overlapping blocks.
165 struct {
philippedfa54a52013-03-13 21:44:07 +0000166 Addr src; // Source block
167 Addr dst; // Destination block
168 SizeT szB; // Size in bytes; 0 if unused.
sewardj7ce71662008-05-02 10:33:15 +0000169 } Overlap;
170
171 // A memory leak.
172 struct {
173 UInt n_this_record;
174 UInt n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000175 LossRecord* lr;
sewardj7ce71662008-05-02 10:33:15 +0000176 } Leak;
177
178 // A memory pool error.
179 struct {
180 AddrInfo ai;
181 } IllegalMempool;
182
florian7b6899d2014-07-13 14:41:55 +0000183 // 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.
187 struct {
188 const HChar *function_name;
189 const HChar *argument_name;
190 SizeT value;
191 } FishyValue;
sewardj7ce71662008-05-02 10:33:15 +0000192 } Err;
193};
194
195
196/*------------------------------------------------------------*/
197/*--- Printing errors ---*/
198/*------------------------------------------------------------*/
199
sewardj6b523cd2009-07-15 14:49:40 +0000200/* 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.
203*/
florian8e3fbb52014-10-20 19:02:38 +0000204void MC_(before_pp_Error) ( const Error* err ) {
sewardj6b523cd2009-07-15 14:49:40 +0000205}
206
207/* Do a printf-style operation on either the XML or normal output
208 channel, depending on the setting of VG_(clo_xml).
209*/
floriandbb35842012-10-27 18:39:11 +0000210static void emit_WRK ( const HChar* format, va_list vargs )
sewardj6b523cd2009-07-15 14:49:40 +0000211{
212 if (VG_(clo_xml)) {
213 VG_(vprintf_xml)(format, vargs);
214 } else {
215 VG_(vmessage)(Vg_UserMsg, format, vargs);
216 }
217}
floriandbb35842012-10-27 18:39:11 +0000218static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2);
219static void emit ( const HChar* format, ... )
sewardj6b523cd2009-07-15 14:49:40 +0000220{
221 va_list vargs;
222 va_start(vargs, format);
223 emit_WRK(format, vargs);
224 va_end(vargs);
225}
sewardj6b523cd2009-07-15 14:49:40 +0000226
227
sewardj7ce71662008-05-02 10:33:15 +0000228static const HChar* str_leak_lossmode ( Reachedness lossmode )
229{
230 const HChar *loss = "?";
231 switch (lossmode) {
232 case Unreached: loss = "definitely lost"; break;
233 case IndirectLeak: loss = "indirectly lost"; break;
njn8225cc02009-03-09 22:52:24 +0000234 case Possible: loss = "possibly lost"; break;
235 case Reachable: loss = "still reachable"; break;
sewardj7ce71662008-05-02 10:33:15 +0000236 }
237 return loss;
238}
239
240static const HChar* xml_leak_kind ( Reachedness lossmode )
241{
242 const HChar *loss = "?";
243 switch (lossmode) {
244 case Unreached: loss = "Leak_DefinitelyLost"; break;
245 case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
njn8225cc02009-03-09 22:52:24 +0000246 case Possible: loss = "Leak_PossiblyLost"; break;
247 case Reachable: loss = "Leak_StillReachable"; break;
sewardj7ce71662008-05-02 10:33:15 +0000248 }
249 return loss;
250}
251
philippeec905f72014-08-17 20:03:51 +0000252const HChar* MC_(parse_leak_kinds_tokens) =
253 "reachable,possible,indirect,definite";
254
255UInt MC_(all_Reachedness)(void)
philippe2193a7c2012-12-08 17:54:16 +0000256{
philippeec905f72014-08-17 20:03:51 +0000257 static UInt all;
258
259 if (all == 0) {
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),
262 True,/*allow_all*/
263 "all",
264 &all);
265 tl_assert (parseok && all);
266 }
267
268 return all;
philippe2193a7c2012-12-08 17:54:16 +0000269}
270
271static const HChar* pp_Reachedness_for_leak_kinds(Reachedness r)
272{
273 switch(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);
279 }
280}
281
sewardj7ce71662008-05-02 10:33:15 +0000282static void mc_pp_origin ( ExeContext* ec, UInt okind )
283{
floriana5f894c2012-10-21 03:43:20 +0000284 const HChar* src = NULL;
sewardj7ce71662008-05-02 10:33:15 +0000285 tl_assert(ec);
286
287 switch (okind) {
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;
292 }
293 tl_assert(src); /* guards against invalid 'okind' */
294
295 if (VG_(clo_xml)) {
sewardj6b523cd2009-07-15 14:49:40 +0000296 emit( " <auxwhat>Uninitialised value was created%s</auxwhat>\n",
297 src);
298 VG_(pp_ExeContext)( ec );
299 } else {
300 emit( " Uninitialised value was created%s\n", src);
301 VG_(pp_ExeContext)( ec );
sewardj7ce71662008-05-02 10:33:15 +0000302 }
303}
304
floriandbb35842012-10-27 18:39:11 +0000305HChar * MC_(snprintf_delta) (HChar * buf, Int size,
306 SizeT current_val, SizeT old_val,
307 LeakCheckDeltaMode delta_mode)
sewardjc8bd1df2011-06-26 12:41:33 +0000308{
floriancf6e7342014-09-28 13:29:06 +0000309 // 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);
314
sewardjc8bd1df2011-06-26 12:41:33 +0000315 if (delta_mode == LCD_Any)
316 buf[0] = '\0';
317 else if (current_val >= old_val)
318 VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val);
319 else
320 VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val);
321
322 return buf;
323}
324
philippea22f59d2012-01-26 23:13:52 +0000325static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
326 LossRecord* lr, Bool xml)
327{
328 // char arrays to produce the indication of increase/decrease in case
329 // of delta_mode != LCD_Any
floriancf6e7342014-09-28 13:29:06 +0000330 HChar d_bytes[31];
331 HChar d_direct_bytes[31];
332 HChar d_indirect_bytes[31];
333 HChar d_num_blocks[31];
philippea22f59d2012-01-26 23:13:52 +0000334
floriancf6e7342014-09-28 13:29:06 +0000335 MC_(snprintf_delta) (d_bytes, sizeof(d_bytes),
philippea22f59d2012-01-26 23:13:52 +0000336 lr->szB + lr->indirect_szB,
337 lr->old_szB + lr->old_indirect_szB,
338 MC_(detect_memory_leaks_last_delta_mode));
floriancf6e7342014-09-28 13:29:06 +0000339 MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes),
philippea22f59d2012-01-26 23:13:52 +0000340 lr->szB,
341 lr->old_szB,
342 MC_(detect_memory_leaks_last_delta_mode));
floriancf6e7342014-09-28 13:29:06 +0000343 MC_(snprintf_delta) (d_indirect_bytes, sizeof(d_indirect_bytes),
philippea22f59d2012-01-26 23:13:52 +0000344 lr->indirect_szB,
345 lr->old_indirect_szB,
346 MC_(detect_memory_leaks_last_delta_mode));
floriancf6e7342014-09-28 13:29:06 +0000347 MC_(snprintf_delta) (d_num_blocks, sizeof(d_num_blocks),
philippea22f59d2012-01-26 23:13:52 +0000348 (SizeT) lr->num_blocks,
349 (SizeT) lr->old_num_blocks,
350 MC_(detect_memory_leaks_last_delta_mode));
351
352 if (xml) {
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 "
357 "in %'u%s blocks"
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" );
370 } else {
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 );
floriande3df032015-08-04 21:26:10 +0000378 emit( " <leakedbytes>%lu</leakedbytes>\n", lr->szB);
379 emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks);
philippea22f59d2012-01-26 23:13:52 +0000380 emit( " </xwhat>\n" );
381 }
382 VG_(pp_ExeContext)(lr->key.allocated_at);
383 } else { /* ! if (xml) */
384 if (lr->indirect_szB > 0) {
385 emit(
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
394 );
395 } else {
396 emit(
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
402 );
403 }
404 VG_(pp_ExeContext)(lr->key.allocated_at);
405 } /* if (xml) */
406}
407
408void MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records,
409 LossRecord* l)
410{
411 pp_LossRecord (n_this_record, n_total_records, l, /* xml */ False);
412}
413
florian8e3fbb52014-10-20 19:02:38 +0000414void MC_(pp_Error) ( const Error* err )
sewardj7ce71662008-05-02 10:33:15 +0000415{
sewardj6b523cd2009-07-15 14:49:40 +0000416 const Bool xml = VG_(clo_xml); /* a shorthand */
sewardj7ce71662008-05-02 10:33:15 +0000417 MC_Error* extra = VG_(get_error_extra)(err);
418
419 switch (VG_(get_error_kind)(err)) {
sewardj6b523cd2009-07-15 14:49:40 +0000420 case Err_CoreMem:
sewardj7ce71662008-05-02 10:33:15 +0000421 /* 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 */
sewardj6b523cd2009-07-15 14:49:40 +0000424 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
425 // the following code is untested. Bad.
426 if (xml) {
427 emit( " <kind>CoreMemError</kind>\n" );
philippe6d0e77b2014-05-07 22:03:59 +0000428 emit( " <what>%pS contains unaddressable byte(s)</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000429 VG_(get_error_string)(err));
430 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
431 } else {
432 emit( "%s contains unaddressable byte(s)\n",
433 VG_(get_error_string)(err));
434 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
435 }
sewardj7ce71662008-05-02 10:33:15 +0000436 break;
sewardj7ce71662008-05-02 10:33:15 +0000437
438 case Err_Value:
439 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000440 if (xml) {
441 emit( " <kind>UninitValue</kind>\n" );
floriande3df032015-08-04 21:26:10 +0000442 emit( " <what>Use of uninitialised value of size %lu</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000443 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 );
sewardj7ce71662008-05-02 10:33:15 +0000448 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000449 /* Could also show extra->Err.Cond.otag if debugging origin
450 tracking */
floriande3df032015-08-04 21:26:10 +0000451 emit( "Use of uninitialised value of size %lu\n",
sewardj6b523cd2009-07-15 14:49:40 +0000452 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 );
sewardj7ce71662008-05-02 10:33:15 +0000457 }
sewardj7ce71662008-05-02 10:33:15 +0000458 break;
459
460 case Err_Cond:
461 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000462 if (xml) {
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 );
sewardj7ce71662008-05-02 10:33:15 +0000470 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000471 /* Could also show extra->Err.Cond.otag if debugging origin
472 tracking */
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 );
sewardj7ce71662008-05-02 10:33:15 +0000479 }
sewardj7ce71662008-05-02 10:33:15 +0000480 break;
481
482 case Err_RegParam:
483 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000484 if (xml) {
485 emit( " <kind>SyscallParam</kind>\n" );
philippe6d0e77b2014-05-07 22:03:59 +0000486 emit( " <what>Syscall param %pS contains "
sewardj6b523cd2009-07-15 14:49:40 +0000487 "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 );
493 } else {
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 );
500 }
sewardj7ce71662008-05-02 10:33:15 +0000501 break;
502
503 case Err_MemParam:
504 if (!extra->Err.MemParam.isAddrErr)
505 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000506 if (xml) {
507 emit( " <kind>SyscallParam</kind>\n" );
philippe6d0e77b2014-05-07 22:03:59 +0000508 emit( " <what>Syscall param %pS points to %s byte(s)</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000509 VG_(get_error_string)(err),
510 extra->Err.MemParam.isAddrErr
511 ? "unaddressable" : "uninitialised" );
512 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000513 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
514 &extra->Err.MemParam.ai, False);
sewardj6b523cd2009-07-15 14:49:40 +0000515 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 );
519 } else {
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) );
philippe07c08522014-05-14 20:39:27 +0000525 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
526 &extra->Err.MemParam.ai, False);
sewardj6b523cd2009-07-15 14:49:40 +0000527 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 );
531 }
sewardj7ce71662008-05-02 10:33:15 +0000532 break;
533
534 case Err_User:
535 if (!extra->Err.User.isAddrErr)
536 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000537 if (xml) {
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) );
philippe07c08522014-05-14 20:39:27 +0000544 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
545 False);
sewardj6b523cd2009-07-15 14:49:40 +0000546 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 );
549 } else {
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) );
philippe07c08522014-05-14 20:39:27 +0000554 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai,
555 False);
sewardj6b523cd2009-07-15 14:49:40 +0000556 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 );
559 }
sewardj7ce71662008-05-02 10:33:15 +0000560 break;
561
562 case Err_Free:
sewardj6b523cd2009-07-15 14:49:40 +0000563 if (xml) {
564 emit( " <kind>InvalidFree</kind>\n" );
bart91347382011-03-25 20:07:25 +0000565 emit( " <what>Invalid free() / delete / delete[]"
566 " / realloc()</what>\n" );
sewardj6b523cd2009-07-15 14:49:40 +0000567 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000568 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
569 &extra->Err.Free.ai, False );
sewardj6b523cd2009-07-15 14:49:40 +0000570 } else {
bart91347382011-03-25 20:07:25 +0000571 emit( "Invalid free() / delete / delete[] / realloc()\n" );
sewardj6b523cd2009-07-15 14:49:40 +0000572 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000573 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
574 &extra->Err.Free.ai, False );
sewardj6b523cd2009-07-15 14:49:40 +0000575 }
sewardj7ce71662008-05-02 10:33:15 +0000576 break;
577
578 case Err_FreeMismatch:
sewardj6b523cd2009-07-15 14:49:40 +0000579 if (xml) {
580 emit( " <kind>MismatchedFree</kind>\n" );
581 emit( " <what>Mismatched free() / delete / delete []</what>\n" );
582 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000583 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
584 &extra->Err.FreeMismatch.ai, False);
sewardj6b523cd2009-07-15 14:49:40 +0000585 } else {
586 emit( "Mismatched free() / delete / delete []\n" );
587 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000588 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err),
589 &extra->Err.FreeMismatch.ai, False);
sewardj6b523cd2009-07-15 14:49:40 +0000590 }
sewardj7ce71662008-05-02 10:33:15 +0000591 break;
592
593 case Err_Addr:
sewardj6b523cd2009-07-15 14:49:40 +0000594 if (xml) {
595 emit( " <kind>Invalid%s</kind>\n",
596 extra->Err.Addr.isWrite ? "Write" : "Read" );
floriande3df032015-08-04 21:26:10 +0000597 emit( " <what>Invalid %s of size %lu</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000598 extra->Err.Addr.isWrite ? "write" : "read",
599 extra->Err.Addr.szB );
600 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000601 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
602 &extra->Err.Addr.ai,
603 extra->Err.Addr.maybe_gcc );
sewardj7ce71662008-05-02 10:33:15 +0000604 } else {
floriande3df032015-08-04 21:26:10 +0000605 emit( "Invalid %s of size %lu\n",
sewardj6b523cd2009-07-15 14:49:40 +0000606 extra->Err.Addr.isWrite ? "write" : "read",
607 extra->Err.Addr.szB );
608 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
609
philippe07c08522014-05-14 20:39:27 +0000610 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
611 &extra->Err.Addr.ai,
612 extra->Err.Addr.maybe_gcc );
sewardj7ce71662008-05-02 10:33:15 +0000613 }
sewardj7ce71662008-05-02 10:33:15 +0000614 break;
615
616 case Err_Jump:
sewardj6b523cd2009-07-15 14:49:40 +0000617 if (xml) {
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) );
philippe07c08522014-05-14 20:39:27 +0000622 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
623 False );
sewardj6b523cd2009-07-15 14:49:40 +0000624 } else {
625 emit( "Jump to the invalid address stated on the next line\n" );
626 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000627 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai,
628 False );
sewardj6b523cd2009-07-15 14:49:40 +0000629 }
sewardj7ce71662008-05-02 10:33:15 +0000630 break;
631
632 case Err_Overlap:
sewardj6b523cd2009-07-15 14:49:40 +0000633 if (xml) {
634 emit( " <kind>Overlap</kind>\n" );
635 if (extra->Err.Overlap.szB == 0) {
philippe6d0e77b2014-05-07 22:03:59 +0000636 emit( " <what>Source and destination overlap "
bartb3af9cf2011-10-06 19:08:37 +0000637 "in %pS(%#lx, %#lx)\n</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000638 VG_(get_error_string)(err),
639 extra->Err.Overlap.dst, extra->Err.Overlap.src );
640 } else {
641 emit( " <what>Source and destination overlap "
florian6a90cfb2014-06-26 11:30:05 +0000642 "in %pS(%#lx, %#lx, %lu)</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000643 VG_(get_error_string)(err),
644 extra->Err.Overlap.dst, extra->Err.Overlap.src,
645 extra->Err.Overlap.szB );
646 }
647 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
648 } else {
649 if (extra->Err.Overlap.szB == 0) {
florian6a90cfb2014-06-26 11:30:05 +0000650 emit( "Source and destination overlap in %s(%#lx, %#lx)\n",
sewardj6b523cd2009-07-15 14:49:40 +0000651 VG_(get_error_string)(err),
652 extra->Err.Overlap.dst, extra->Err.Overlap.src );
653 } else {
philippedfa54a52013-03-13 21:44:07 +0000654 emit( "Source and destination overlap in %s(%#lx, %#lx, %lu)\n",
sewardj6b523cd2009-07-15 14:49:40 +0000655 VG_(get_error_string)(err),
656 extra->Err.Overlap.dst, extra->Err.Overlap.src,
657 extra->Err.Overlap.szB );
658 }
659 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
660 }
sewardj7ce71662008-05-02 10:33:15 +0000661 break;
662
663 case Err_IllegalMempool:
sewardj6b523cd2009-07-15 14:49:40 +0000664 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
665 // the following code is untested. Bad.
666 if (xml) {
667 emit( " <kind>InvalidMemPool</kind>\n" );
668 emit( " <what>Illegal memory pool address</what>\n" );
669 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000670 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
671 &extra->Err.IllegalMempool.ai, False );
sewardj6b523cd2009-07-15 14:49:40 +0000672 } else {
673 emit( "Illegal memory pool address\n" );
674 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
philippe07c08522014-05-14 20:39:27 +0000675 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err),
676 &extra->Err.IllegalMempool.ai, False );
sewardj6b523cd2009-07-15 14:49:40 +0000677 }
sewardj7ce71662008-05-02 10:33:15 +0000678 break;
679
680 case Err_Leak: {
sewardj7ce71662008-05-02 10:33:15 +0000681 UInt n_this_record = extra->Err.Leak.n_this_record;
682 UInt n_total_records = extra->Err.Leak.n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000683 LossRecord* lr = extra->Err.Leak.lr;
philippea22f59d2012-01-26 23:13:52 +0000684 pp_LossRecord (n_this_record, n_total_records, lr, xml);
sewardj7ce71662008-05-02 10:33:15 +0000685 break;
686 }
687
florian7b6899d2014-07-13 14:41:55 +0000688 case Err_FishyValue:
689 if (xml) {
690 emit( " <kind>FishyValue</kind>\n" );
691 emit( " <what>");
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);
697 emit( "</what>");
698 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
699 } else {
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) );
706 }
707 break;
708
sewardj7ce71662008-05-02 10:33:15 +0000709 default:
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)");
713 }
714}
715
716/*------------------------------------------------------------*/
717/*--- Recording errors ---*/
718/*------------------------------------------------------------*/
719
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
723
724/* Is this address within some small distance below %ESP? Used only
725 for the --workaround-gcc296-bugs kludge. */
726static Bool is_just_below_ESP( Addr esp, Addr aa )
727{
sewardj7d751b22010-07-21 12:46:44 +0000728 esp -= VG_STACK_REDZONE_SZB;
sewardj7ce71662008-05-02 10:33:15 +0000729 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
730 return True;
731 else
732 return False;
733}
734
735/* --- Called from generated and non-generated code --- */
736
737void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
738 Bool isWrite )
739{
740 MC_Error extra;
741 Bool just_below_esp;
742
743 if (MC_(in_ignored_range)(a))
744 return;
745
sewardj3b290482011-05-06 21:02:55 +0000746 if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB))
747 return;
748
Elliott Hughesa0664b92017-04-18 17:46:52 -0700749 Addr current_sp = VG_(get_SP)(tid);
750 just_below_esp = is_just_below_ESP( current_sp, a );
sewardj7ce71662008-05-02 10:33:15 +0000751
752 /* If this is caused by an access immediately below %ESP, and the
753 user asks nicely, we just ignore it. */
754 if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
755 return;
756
Elliott Hughesa0664b92017-04-18 17:46:52 -0700757 /* Also, if this is caused by an access in the range of offsets
758 below the stack pointer as described by
759 --ignore-range-below-sp, ignore it. */
760 if (MC_(in_ignored_range_below_sp)( current_sp, a, szB ))
761 return;
762
sewardj7ce71662008-05-02 10:33:15 +0000763 extra.Err.Addr.isWrite = isWrite;
764 extra.Err.Addr.szB = szB;
765 extra.Err.Addr.maybe_gcc = just_below_esp;
766 extra.Err.Addr.ai.tag = Addr_Undescribed;
767 VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
768}
769
770void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
771{
772 MC_Error extra;
773 tl_assert( MC_(clo_mc_level) >= 2 );
774 if (otag > 0)
775 tl_assert( MC_(clo_mc_level) == 3 );
776 extra.Err.Value.szB = szB;
777 extra.Err.Value.otag = otag;
778 extra.Err.Value.origin_ec = NULL; /* Filled in later */
779 VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
780}
781
782void MC_(record_cond_error) ( ThreadId tid, UInt otag )
783{
784 MC_Error extra;
785 tl_assert( MC_(clo_mc_level) >= 2 );
786 if (otag > 0)
787 tl_assert( MC_(clo_mc_level) == 3 );
788 extra.Err.Cond.otag = otag;
789 extra.Err.Cond.origin_ec = NULL; /* Filled in later */
790 VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
791}
792
793/* --- Called from non-generated code --- */
794
njn1dcee092009-02-24 03:07:37 +0000795/* This is for memory errors in signal-related memory. */
floriane543f302012-10-21 19:43:43 +0000796void MC_(record_core_mem_error) ( ThreadId tid, const HChar* msg )
sewardj7ce71662008-05-02 10:33:15 +0000797{
798 VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
799}
800
floriane543f302012-10-21 19:43:43 +0000801void MC_(record_regparam_error) ( ThreadId tid, const HChar* msg, UInt otag )
sewardj7ce71662008-05-02 10:33:15 +0000802{
803 MC_Error extra;
804 tl_assert(VG_INVALID_THREADID != tid);
805 if (otag > 0)
806 tl_assert( MC_(clo_mc_level) == 3 );
807 extra.Err.RegParam.otag = otag;
808 extra.Err.RegParam.origin_ec = NULL; /* Filled in later */
809 VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
810}
811
812void MC_(record_memparam_error) ( ThreadId tid, Addr a,
floriane543f302012-10-21 19:43:43 +0000813 Bool isAddrErr, const HChar* msg, UInt otag )
sewardj7ce71662008-05-02 10:33:15 +0000814{
815 MC_Error extra;
816 tl_assert(VG_INVALID_THREADID != tid);
817 if (!isAddrErr)
818 tl_assert( MC_(clo_mc_level) >= 2 );
819 if (otag != 0) {
820 tl_assert( MC_(clo_mc_level) == 3 );
821 tl_assert( !isAddrErr );
822 }
823 extra.Err.MemParam.isAddrErr = isAddrErr;
824 extra.Err.MemParam.ai.tag = Addr_Undescribed;
825 extra.Err.MemParam.otag = otag;
826 extra.Err.MemParam.origin_ec = NULL; /* Filled in later */
827 VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
828}
829
830void MC_(record_jump_error) ( ThreadId tid, Addr a )
831{
832 MC_Error extra;
833 tl_assert(VG_INVALID_THREADID != tid);
834 extra.Err.Jump.ai.tag = Addr_Undescribed;
835 VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
836}
837
838void MC_(record_free_error) ( ThreadId tid, Addr a )
839{
840 MC_Error extra;
841 tl_assert(VG_INVALID_THREADID != tid);
842 extra.Err.Free.ai.tag = Addr_Undescribed;
843 VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
844}
845
846void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
847{
848 MC_Error extra;
849 AddrInfo* ai = &extra.Err.FreeMismatch.ai;
850 tl_assert(VG_INVALID_THREADID != tid);
851 ai->tag = Addr_Block;
852 ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed'
853 ai->Addr.Block.block_desc = "block";
854 ai->Addr.Block.block_szB = mc->szB;
855 ai->Addr.Block.rwoffset = 0;
philippe8617b5b2013-01-12 19:53:08 +0000856 ai->Addr.Block.allocated_at = MC_(allocated_at) (mc);
philippe0c9ac8d2014-07-18 00:03:58 +0000857 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
philippe8617b5b2013-01-12 19:53:08 +0000858 ai->Addr.Block.freed_at = MC_(freed_at) (mc);
sewardj7ce71662008-05-02 10:33:15 +0000859 VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
860 &extra );
861}
862
863void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
864{
865 MC_Error extra;
866 tl_assert(VG_INVALID_THREADID != tid);
867 extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
868 VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
869}
870
floriane543f302012-10-21 19:43:43 +0000871void MC_(record_overlap_error) ( ThreadId tid, const HChar* function,
sewardj7ce71662008-05-02 10:33:15 +0000872 Addr src, Addr dst, SizeT szB )
873{
874 MC_Error extra;
875 tl_assert(VG_INVALID_THREADID != tid);
876 extra.Err.Overlap.src = src;
877 extra.Err.Overlap.dst = dst;
878 extra.Err.Overlap.szB = szB;
879 VG_(maybe_record_error)(
880 tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
881}
882
883Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
njnb7a4e2e2009-05-01 00:30:43 +0000884 UInt n_total_records, LossRecord* lr,
njn18afe5d2009-08-10 08:25:39 +0000885 Bool print_record, Bool count_error )
sewardj7ce71662008-05-02 10:33:15 +0000886{
887 MC_Error extra;
888 extra.Err.Leak.n_this_record = n_this_record;
889 extra.Err.Leak.n_total_records = n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000890 extra.Err.Leak.lr = lr;
sewardj7ce71662008-05-02 10:33:15 +0000891 return
892 VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
njn29a5c012009-05-06 06:15:55 +0000893 lr->key.allocated_at, print_record,
njn18afe5d2009-08-10 08:25:39 +0000894 /*allow_GDB_attach*/False, count_error );
sewardj7ce71662008-05-02 10:33:15 +0000895}
896
florian7b6899d2014-07-13 14:41:55 +0000897Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name,
898 const HChar *argument_name, SizeT value)
899{
900 MC_Error extra;
901
902 tl_assert(VG_INVALID_THREADID != tid);
903
904 if ((SSizeT)value >= 0) return False; // not a fishy value
905
906 extra.Err.FishyValue.function_name = function_name;
907 extra.Err.FishyValue.argument_name = argument_name;
908 extra.Err.FishyValue.value = value;
909
910 VG_(maybe_record_error)(
911 tid, Err_FishyValue, /*addr*/0, /*s*/NULL, &extra );
912
913 return True;
914}
915
sewardj7ce71662008-05-02 10:33:15 +0000916void MC_(record_user_error) ( ThreadId tid, Addr a,
917 Bool isAddrErr, UInt otag )
918{
919 MC_Error extra;
920 if (otag != 0) {
921 tl_assert(!isAddrErr);
922 tl_assert( MC_(clo_mc_level) == 3 );
923 }
924 if (!isAddrErr) {
925 tl_assert( MC_(clo_mc_level) >= 2 );
926 }
927 tl_assert(VG_INVALID_THREADID != tid);
928 extra.Err.User.isAddrErr = isAddrErr;
929 extra.Err.User.ai.tag = Addr_Undescribed;
930 extra.Err.User.otag = otag;
931 extra.Err.User.origin_ec = NULL; /* Filled in later */
932 VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
933}
934
Elliott Hughesa0664b92017-04-18 17:46:52 -0700935Bool MC_(is_mempool_block)(MC_Chunk* mc_search)
936{
937 MC_Mempool* mp;
938
939 if (!MC_(mempool_list))
940 return False;
941
942 // A chunk can only come from a mempool if a custom allocator
943 // is used. No search required for other kinds.
944 if (mc_search->allockind == MC_AllocCustom) {
945 VG_(HT_ResetIter)( MC_(mempool_list) );
946 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
947 MC_Chunk* mc;
948 VG_(HT_ResetIter)(mp->chunks);
949 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
950 if (mc == mc_search)
951 return True;
952 }
953 }
954 }
955
956 return False;
957}
958
sewardj7ce71662008-05-02 10:33:15 +0000959/*------------------------------------------------------------*/
960/*--- Other error operations ---*/
961/*------------------------------------------------------------*/
962
963/* Compare error contexts, to detect duplicates. Note that if they
964 are otherwise the same, the faulting addrs and associated rwoffsets
965 are allowed to be different. */
florian8e3fbb52014-10-20 19:02:38 +0000966Bool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 )
sewardj7ce71662008-05-02 10:33:15 +0000967{
968 MC_Error* extra1 = VG_(get_error_extra)(e1);
969 MC_Error* extra2 = VG_(get_error_extra)(e2);
970
971 /* Guaranteed by calling function */
972 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
973
974 switch (VG_(get_error_kind)(e1)) {
975 case Err_CoreMem: {
floriane543f302012-10-21 19:43:43 +0000976 const HChar *e1s, *e2s;
sewardj7ce71662008-05-02 10:33:15 +0000977 e1s = VG_(get_error_string)(e1);
978 e2s = VG_(get_error_string)(e2);
979 if (e1s == e2s) return True;
980 if (VG_STREQ(e1s, e2s)) return True;
981 return False;
982 }
983
984 case Err_RegParam:
985 return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
986
987 // Perhaps we should also check the addrinfo.akinds for equality.
988 // That would result in more error reports, but only in cases where
989 // a register contains uninitialised bytes and points to memory
990 // containing uninitialised bytes. Currently, the 2nd of those to be
991 // detected won't be reported. That is (nearly?) always the memory
992 // error, which is good.
993 case Err_MemParam:
994 if (!VG_STREQ(VG_(get_error_string)(e1),
995 VG_(get_error_string)(e2))) return False;
996 // fall through
997 case Err_User:
998 return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
999 ? True : False );
1000
1001 case Err_Free:
1002 case Err_FreeMismatch:
1003 case Err_Jump:
1004 case Err_IllegalMempool:
1005 case Err_Overlap:
1006 case Err_Cond:
1007 return True;
1008
florian7b6899d2014-07-13 14:41:55 +00001009 case Err_FishyValue:
1010 return VG_STREQ(extra1->Err.FishyValue.function_name,
1011 extra2->Err.FishyValue.function_name) &&
1012 VG_STREQ(extra1->Err.FishyValue.argument_name,
1013 extra2->Err.FishyValue.argument_name);
1014
sewardj7ce71662008-05-02 10:33:15 +00001015 case Err_Addr:
1016 return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
1017 ? True : False );
1018
1019 case Err_Value:
1020 return ( extra1->Err.Value.szB == extra2->Err.Value.szB
1021 ? True : False );
1022
1023 case Err_Leak:
1024 VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
1025 "since it's handled with VG_(unique_error)()!");
1026
1027 default:
1028 VG_(printf)("Error:\n unknown error code %d\n",
1029 VG_(get_error_kind)(e1));
1030 VG_(tool_panic)("unknown error code in mc_eq_Error");
1031 }
1032}
1033
sewardj62b91042011-01-23 20:45:53 +00001034/* Functions used when searching MC_Chunk lists */
1035static
1036Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
sewardj7ce71662008-05-02 10:33:15 +00001037{
sewardj7ce71662008-05-02 10:33:15 +00001038 return VG_(addr_is_in_block)( a, mc->data, mc->szB,
philipped99c26a2012-07-31 22:17:28 +00001039 MC_(Malloc_Redzone_SzB) );
sewardj7ce71662008-05-02 10:33:15 +00001040}
sewardj62b91042011-01-23 20:45:53 +00001041static
1042Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
1043{
1044 return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1045 rzB );
1046}
sewardj7ce71662008-05-02 10:33:15 +00001047
sewardj62b91042011-01-23 20:45:53 +00001048// Forward declarations
sewardj7ce71662008-05-02 10:33:15 +00001049static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
Elliott Hughesa0664b92017-04-18 17:46:52 -07001050static Bool mempool_block_maybe_describe( Addr a, Bool is_metapool,
1051 AddrInfo* ai );
sewardj7ce71662008-05-02 10:33:15 +00001052
1053
1054/* Describe an address as best you can, for error messages,
1055 putting the result in ai. */
1056static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
1057{
1058 MC_Chunk* mc;
sewardj7ce71662008-05-02 10:33:15 +00001059
1060 tl_assert(Addr_Undescribed == ai->tag);
1061
sewardj62b91042011-01-23 20:45:53 +00001062 /* -- Perhaps it's a user-named block? -- */
sewardj7ce71662008-05-02 10:33:15 +00001063 if (client_block_maybe_describe( a, ai )) {
1064 return;
1065 }
Elliott Hughesa0664b92017-04-18 17:46:52 -07001066
1067 /* -- Perhaps it's in mempool block (non-meta)? -- */
1068 if (mempool_block_maybe_describe( a, /*is_metapool*/ False, ai)) {
sewardj62b91042011-01-23 20:45:53 +00001069 return;
1070 }
Elliott Hughesa0664b92017-04-18 17:46:52 -07001071
philippe11cc9ce2012-03-11 17:59:00 +00001072 /* Blocks allocated by memcheck malloc functions are either
1073 on the recently freed list or on the malloc-ed list.
1074 Custom blocks can be on both : a recently freed block might
1075 have been just re-allocated.
1076 So, first search the malloc-ed block, as the most recent
1077 block is the probable cause of error.
1078 We however detect and report that this is a recently re-allocated
1079 block. */
1080 /* -- Search for a currently malloc'd block which might bracket it. -- */
1081 VG_(HT_ResetIter)(MC_(malloc_list));
1082 while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
Elliott Hughesa0664b92017-04-18 17:46:52 -07001083 if (!MC_(is_mempool_block)(mc) &&
1084 addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
philippe11cc9ce2012-03-11 17:59:00 +00001085 ai->tag = Addr_Block;
1086 ai->Addr.Block.block_kind = Block_Mallocd;
1087 if (MC_(get_freed_block_bracketting)( a ))
1088 ai->Addr.Block.block_desc = "recently re-allocated block";
1089 else
1090 ai->Addr.Block.block_desc = "block";
1091 ai->Addr.Block.block_szB = mc->szB;
1092 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
philippe8617b5b2013-01-12 19:53:08 +00001093 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
philippe0c9ac8d2014-07-18 00:03:58 +00001094 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
philippe8617b5b2013-01-12 19:53:08 +00001095 ai->Addr.Block.freed_at = MC_(freed_at)(mc);
philippe11cc9ce2012-03-11 17:59:00 +00001096 return;
1097 }
1098 }
sewardj6b523cd2009-07-15 14:49:40 +00001099 /* -- Search for a recently freed block which might bracket it. -- */
sewardj403d8aa2011-10-22 19:48:57 +00001100 mc = MC_(get_freed_block_bracketting)( a );
Elliott Hughesed398002017-06-21 14:41:24 -07001101 if (mc) {
sewardj403d8aa2011-10-22 19:48:57 +00001102 ai->tag = Addr_Block;
1103 ai->Addr.Block.block_kind = Block_Freed;
1104 ai->Addr.Block.block_desc = "block";
1105 ai->Addr.Block.block_szB = mc->szB;
1106 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
philippe8617b5b2013-01-12 19:53:08 +00001107 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
philippe0c9ac8d2014-07-18 00:03:58 +00001108 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
philippe8617b5b2013-01-12 19:53:08 +00001109 ai->Addr.Block.freed_at = MC_(freed_at)(mc);
sewardj403d8aa2011-10-22 19:48:57 +00001110 return;
sewardj7ce71662008-05-02 10:33:15 +00001111 }
sewardj6b523cd2009-07-15 14:49:40 +00001112
Elliott Hughesa0664b92017-04-18 17:46:52 -07001113 /* -- Perhaps it's in a meta mempool block? -- */
1114 /* This test is done last, because metapool blocks overlap with blocks
1115 handed out to the application. That makes every heap address part of
1116 a metapool block, so the interesting cases are handled first.
1117 This final search is a last-ditch attempt. When found, it is probably
1118 an error in the custom allocator itself. */
1119 if (mempool_block_maybe_describe( a, /*is_metapool*/ True, ai )) {
1120 return;
1121 }
1122
philippe07c08522014-05-14 20:39:27 +00001123 /* No block found. Search a non-heap block description. */
1124 VG_(describe_addr) (a, ai);
sewardj7ce71662008-05-02 10:33:15 +00001125}
1126
sewardj3b290482011-05-06 21:02:55 +00001127void MC_(pp_describe_addr) ( Addr a )
1128{
1129 AddrInfo ai;
1130
1131 ai.tag = Addr_Undescribed;
1132 describe_addr (a, &ai);
philippe07c08522014-05-14 20:39:27 +00001133 VG_(pp_addrinfo_mc) (a, &ai, /* maybe_gcc */ False);
philippef7ec77f2014-11-24 17:46:41 +00001134 VG_(clear_addrinfo) (&ai);
sewardj3b290482011-05-06 21:02:55 +00001135}
1136
sewardj7ce71662008-05-02 10:33:15 +00001137/* Fill in *origin_ec as specified by otag, or NULL it out if otag
1138 does not refer to a known origin. */
1139static void update_origin ( /*OUT*/ExeContext** origin_ec,
1140 UInt otag )
1141{
1142 UInt ecu = otag & ~3;
1143 *origin_ec = NULL;
1144 if (VG_(is_plausible_ECU)(ecu)) {
1145 *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
1146 }
1147}
1148
1149/* Updates the copy with address info if necessary (but not for all errors). */
florian8e3fbb52014-10-20 19:02:38 +00001150UInt MC_(update_Error_extra)( const Error* err )
sewardj7ce71662008-05-02 10:33:15 +00001151{
1152 MC_Error* extra = VG_(get_error_extra)(err);
1153
1154 switch (VG_(get_error_kind)(err)) {
1155 // These ones don't have addresses associated with them, and so don't
1156 // need any updating.
1157 case Err_CoreMem:
1158 //case Err_Value:
1159 //case Err_Cond:
1160 case Err_Overlap:
florian7b6899d2014-07-13 14:41:55 +00001161 case Err_FishyValue:
sewardj7ce71662008-05-02 10:33:15 +00001162 // For Err_Leaks the returned size does not matter -- they are always
1163 // shown with VG_(unique_error)() so they 'extra' not copied. But
1164 // we make it consistent with the others.
1165 case Err_Leak:
1166 return sizeof(MC_Error);
1167
1168 // For value errors, get the ExeContext corresponding to the
1169 // origin tag. Note that it is a kludge to assume that
1170 // a length-1 trace indicates a stack origin. FIXME.
1171 case Err_Value:
1172 update_origin( &extra->Err.Value.origin_ec,
1173 extra->Err.Value.otag );
1174 return sizeof(MC_Error);
1175 case Err_Cond:
1176 update_origin( &extra->Err.Cond.origin_ec,
1177 extra->Err.Cond.otag );
1178 return sizeof(MC_Error);
1179 case Err_RegParam:
1180 update_origin( &extra->Err.RegParam.origin_ec,
1181 extra->Err.RegParam.otag );
1182 return sizeof(MC_Error);
1183
1184 // These ones always involve a memory address.
1185 case Err_Addr:
1186 describe_addr ( VG_(get_error_address)(err),
1187 &extra->Err.Addr.ai );
1188 return sizeof(MC_Error);
1189 case Err_MemParam:
1190 describe_addr ( VG_(get_error_address)(err),
1191 &extra->Err.MemParam.ai );
1192 update_origin( &extra->Err.MemParam.origin_ec,
1193 extra->Err.MemParam.otag );
1194 return sizeof(MC_Error);
1195 case Err_Jump:
1196 describe_addr ( VG_(get_error_address)(err),
1197 &extra->Err.Jump.ai );
1198 return sizeof(MC_Error);
1199 case Err_User:
1200 describe_addr ( VG_(get_error_address)(err),
1201 &extra->Err.User.ai );
1202 update_origin( &extra->Err.User.origin_ec,
1203 extra->Err.User.otag );
1204 return sizeof(MC_Error);
1205 case Err_Free:
1206 describe_addr ( VG_(get_error_address)(err),
1207 &extra->Err.Free.ai );
1208 return sizeof(MC_Error);
1209 case Err_IllegalMempool:
1210 describe_addr ( VG_(get_error_address)(err),
1211 &extra->Err.IllegalMempool.ai );
1212 return sizeof(MC_Error);
1213
1214 // Err_FreeMismatches have already had their address described; this is
1215 // possible because we have the MC_Chunk on hand when the error is
1216 // detected. However, the address may be part of a user block, and if so
1217 // we override the pre-determined description with a user block one.
1218 case Err_FreeMismatch: {
1219 tl_assert(extra && Block_Mallocd ==
1220 extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
1221 (void)client_block_maybe_describe( VG_(get_error_address)(err),
1222 &extra->Err.FreeMismatch.ai );
1223 return sizeof(MC_Error);
1224 }
1225
1226 default: VG_(tool_panic)("mc_update_extra: bad errkind");
1227 }
1228}
1229
sewardj62b91042011-01-23 20:45:53 +00001230
sewardj7ce71662008-05-02 10:33:15 +00001231static Bool client_block_maybe_describe( Addr a,
1232 /*OUT*/AddrInfo* ai )
1233{
sewardj56adc352008-05-02 11:25:17 +00001234 UWord i;
sewardj7ce71662008-05-02 10:33:15 +00001235 CGenBlock* cgbs = NULL;
1236 UWord cgb_used = 0;
sewardj56adc352008-05-02 11:25:17 +00001237
sewardj7ce71662008-05-02 10:33:15 +00001238 MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
1239 if (cgbs == NULL)
1240 tl_assert(cgb_used == 0);
1241
1242 /* Perhaps it's a general block ? */
1243 for (i = 0; i < cgb_used; i++) {
1244 if (cgbs[i].start == 0 && cgbs[i].size == 0)
1245 continue;
1246 // Use zero as the redzone for client blocks.
1247 if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
sewardj7ce71662008-05-02 10:33:15 +00001248 ai->tag = Addr_Block;
1249 ai->Addr.Block.block_kind = Block_UserG;
1250 ai->Addr.Block.block_desc = cgbs[i].desc;
1251 ai->Addr.Block.block_szB = cgbs[i].size;
sewardj56adc352008-05-02 11:25:17 +00001252 ai->Addr.Block.rwoffset = (Word)(a) - (Word)(cgbs[i].start);
philippe8617b5b2013-01-12 19:53:08 +00001253 ai->Addr.Block.allocated_at = cgbs[i].where;
philippe0c9ac8d2014-07-18 00:03:58 +00001254 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
philippe8617b5b2013-01-12 19:53:08 +00001255 ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
sewardj7ce71662008-05-02 10:33:15 +00001256 return True;
1257 }
1258 }
1259 return False;
1260}
1261
1262
Elliott Hughesa0664b92017-04-18 17:46:52 -07001263static Bool mempool_block_maybe_describe( Addr a, Bool is_metapool,
sewardj62b91042011-01-23 20:45:53 +00001264 /*OUT*/AddrInfo* ai )
1265{
1266 MC_Mempool* mp;
1267 tl_assert( MC_(mempool_list) );
1268
1269 VG_(HT_ResetIter)( MC_(mempool_list) );
1270 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
Elliott Hughesa0664b92017-04-18 17:46:52 -07001271 if (mp->chunks != NULL && mp->metapool == is_metapool) {
sewardj62b91042011-01-23 20:45:53 +00001272 MC_Chunk* mc;
1273 VG_(HT_ResetIter)(mp->chunks);
1274 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
1275 if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
1276 ai->tag = Addr_Block;
1277 ai->Addr.Block.block_kind = Block_MempoolChunk;
1278 ai->Addr.Block.block_desc = "block";
1279 ai->Addr.Block.block_szB = mc->szB;
1280 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
philippe8617b5b2013-01-12 19:53:08 +00001281 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
philippe0c9ac8d2014-07-18 00:03:58 +00001282 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
philippe8617b5b2013-01-12 19:53:08 +00001283 ai->Addr.Block.freed_at = MC_(freed_at)(mc);
sewardj62b91042011-01-23 20:45:53 +00001284 return True;
1285 }
1286 }
1287 }
1288 }
1289 return False;
1290}
1291
1292
sewardj7ce71662008-05-02 10:33:15 +00001293/*------------------------------------------------------------*/
1294/*--- Suppressions ---*/
1295/*------------------------------------------------------------*/
1296
1297typedef
1298 enum {
1299 ParamSupp, // Bad syscall params
1300 UserSupp, // Errors arising from client-request checks
1301 CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
1302
1303 // Undefined value errors of given size
rhyskidd9d83e992015-07-01 23:04:58 +00001304 Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, Value32Supp,
sewardj7ce71662008-05-02 10:33:15 +00001305
1306 // Undefined value error in conditional.
1307 CondSupp,
1308
1309 // Unaddressable read/write attempt at given size
rhyskidd9d83e992015-07-01 23:04:58 +00001310 Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp,
sewardj7ce71662008-05-02 10:33:15 +00001311
1312 JumpSupp, // Jump to unaddressable target
1313 FreeSupp, // Invalid or mismatching free
1314 OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
1315 LeakSupp, // Something to be suppressed in a leak check.
1316 MempoolSupp, // Memory pool suppression.
florian7b6899d2014-07-13 14:41:55 +00001317 FishyValueSupp,// Fishy value suppression.
sewardj7ce71662008-05-02 10:33:15 +00001318 }
1319 MC_SuppKind;
1320
florian19f91bb2012-11-10 22:29:54 +00001321Bool MC_(is_recognised_suppression) ( const HChar* name, Supp* su )
sewardj7ce71662008-05-02 10:33:15 +00001322{
1323 SuppKind skind;
1324
1325 if (VG_STREQ(name, "Param")) skind = ParamSupp;
1326 else if (VG_STREQ(name, "User")) skind = UserSupp;
1327 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
1328 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
1329 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
1330 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
1331 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
1332 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
rhyskidd9d83e992015-07-01 23:04:58 +00001333 else if (VG_STREQ(name, "Addr32")) skind = Addr32Supp;
sewardj7ce71662008-05-02 10:33:15 +00001334 else if (VG_STREQ(name, "Jump")) skind = JumpSupp;
1335 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
1336 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
1337 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
1338 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
1339 else if (VG_STREQ(name, "Cond")) skind = CondSupp;
1340 else if (VG_STREQ(name, "Value0")) skind = CondSupp; /* backwards compat */
1341 else if (VG_STREQ(name, "Value1")) skind = Value1Supp;
1342 else if (VG_STREQ(name, "Value2")) skind = Value2Supp;
1343 else if (VG_STREQ(name, "Value4")) skind = Value4Supp;
1344 else if (VG_STREQ(name, "Value8")) skind = Value8Supp;
1345 else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
rhyskidd9d83e992015-07-01 23:04:58 +00001346 else if (VG_STREQ(name, "Value32")) skind = Value32Supp;
florian7b6899d2014-07-13 14:41:55 +00001347 else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp;
sewardj7ce71662008-05-02 10:33:15 +00001348 else
1349 return False;
1350
1351 VG_(set_supp_kind)(su, skind);
1352 return True;
1353}
1354
philippe2193a7c2012-12-08 17:54:16 +00001355typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra;
1356
1357struct _MC_LeakSuppExtra {
1358 UInt match_leak_kinds;
philippe4e32d672013-10-17 22:10:41 +00001359
1360 /* Maintains nr of blocks and bytes suppressed with this suppression
1361 during the leak search identified by leak_search_gen.
1362 blocks_suppressed and bytes_suppressed are reset to 0 when
1363 used the first time during a leak search. */
1364 SizeT blocks_suppressed;
1365 SizeT bytes_suppressed;
1366 UInt leak_search_gen;
philippe2193a7c2012-12-08 17:54:16 +00001367};
1368
florian7b6899d2014-07-13 14:41:55 +00001369typedef struct {
1370 const HChar *function_name;
1371 const HChar *argument_name;
1372} MC_FishyValueExtra;
1373
florian19f91bb2012-11-10 22:29:54 +00001374Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
philippe362441d2013-07-22 22:00:13 +00001375 SizeT* nBufp, Int* lineno, Supp *su )
sewardj7ce71662008-05-02 10:33:15 +00001376{
1377 Bool eof;
philippe2193a7c2012-12-08 17:54:16 +00001378 Int i;
sewardj7ce71662008-05-02 10:33:15 +00001379
1380 if (VG_(get_supp_kind)(su) == ParamSupp) {
philippe362441d2013-07-22 22:00:13 +00001381 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
sewardj7ce71662008-05-02 10:33:15 +00001382 if (eof) return False;
njn35db56c2009-07-24 07:38:29 +00001383 VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
philippe2193a7c2012-12-08 17:54:16 +00001384 } else if (VG_(get_supp_kind)(su) == LeakSupp) {
1385 // We might have the optional match-leak-kinds line
1386 MC_LeakSuppExtra* lse;
1387 lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
philippeec905f72014-08-17 20:03:51 +00001388 lse->match_leak_kinds = MC_(all_Reachedness)();
philippe4e32d672013-10-17 22:10:41 +00001389 lse->blocks_suppressed = 0;
1390 lse->bytes_suppressed = 0;
1391 lse->leak_search_gen = 0;
philippe2193a7c2012-12-08 17:54:16 +00001392 VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
philippe362441d2013-07-22 22:00:13 +00001393 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
philippe2193a7c2012-12-08 17:54:16 +00001394 if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
1395 if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) {
1396 i = 17;
Elliott Hughesa0664b92017-04-18 17:46:52 -07001397 while ((*bufpp)[i] && VG_(isspace)((*bufpp)[i]))
philippe2193a7c2012-12-08 17:54:16 +00001398 i++;
philippeec905f72014-08-17 20:03:51 +00001399 if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
1400 True/*allow_all*/,
1401 (*bufpp)+i, &lse->match_leak_kinds)) {
philippe2193a7c2012-12-08 17:54:16 +00001402 return False;
1403 }
1404 } else {
1405 return False; // unknown extra line.
1406 }
florian7b6899d2014-07-13 14:41:55 +00001407 } else if (VG_(get_supp_kind)(su) == FishyValueSupp) {
1408 MC_FishyValueExtra *extra;
florian659efde2014-09-12 20:53:43 +00001409 HChar *p, *function_name, *argument_name = NULL;
florian7b6899d2014-07-13 14:41:55 +00001410
1411 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
1412 if (eof) return True;
1413
florian7b6899d2014-07-13 14:41:55 +00001414 // The suppression string is: function_name(argument_name)
florian659efde2014-09-12 20:53:43 +00001415 function_name = VG_(strdup)("mv.resi.4", *bufpp);
1416 p = VG_(strchr)(function_name, '(');
1417 if (p != NULL) {
1418 *p++ = '\0';
1419 argument_name = p;
1420 p = VG_(strchr)(p, ')');
1421 if (p != NULL)
1422 *p = '\0';
1423 }
1424 if (p == NULL) { // malformed suppression string
1425 VG_(free)(function_name);
1426 return False;
1427 }
1428
1429 extra = VG_(malloc)("mc.resi.3", sizeof *extra);
1430 extra->function_name = function_name;
1431 extra->argument_name = argument_name;
florian7b6899d2014-07-13 14:41:55 +00001432
1433 VG_(set_supp_extra)(su, extra);
sewardj7ce71662008-05-02 10:33:15 +00001434 }
1435 return True;
1436}
1437
florian8e3fbb52014-10-20 19:02:38 +00001438Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su )
sewardj7ce71662008-05-02 10:33:15 +00001439{
1440 Int su_szB;
1441 MC_Error* extra = VG_(get_error_extra)(err);
Elliott Hughesa0664b92017-04-18 17:46:52 -07001442 ErrorKind ekind = VG_(get_error_kind)(err);
sewardj7ce71662008-05-02 10:33:15 +00001443
1444 switch (VG_(get_supp_kind)(su)) {
1445 case ParamSupp:
1446 return ((ekind == Err_RegParam || ekind == Err_MemParam)
1447 && VG_STREQ(VG_(get_error_string)(err),
1448 VG_(get_supp_string)(su)));
1449
1450 case UserSupp:
1451 return (ekind == Err_User);
1452
1453 case CoreMemSupp:
1454 return (ekind == Err_CoreMem
1455 && VG_STREQ(VG_(get_error_string)(err),
1456 VG_(get_supp_string)(su)));
1457
1458 case Value1Supp: su_szB = 1; goto value_case;
1459 case Value2Supp: su_szB = 2; goto value_case;
1460 case Value4Supp: su_szB = 4; goto value_case;
1461 case Value8Supp: su_szB = 8; goto value_case;
1462 case Value16Supp:su_szB =16; goto value_case;
rhyskidd9d83e992015-07-01 23:04:58 +00001463 case Value32Supp:su_szB =32; goto value_case;
sewardj7ce71662008-05-02 10:33:15 +00001464 value_case:
1465 return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
1466
1467 case CondSupp:
1468 return (ekind == Err_Cond);
1469
1470 case Addr1Supp: su_szB = 1; goto addr_case;
1471 case Addr2Supp: su_szB = 2; goto addr_case;
1472 case Addr4Supp: su_szB = 4; goto addr_case;
1473 case Addr8Supp: su_szB = 8; goto addr_case;
1474 case Addr16Supp:su_szB =16; goto addr_case;
rhyskidd9d83e992015-07-01 23:04:58 +00001475 case Addr32Supp:su_szB =32; goto addr_case;
sewardj7ce71662008-05-02 10:33:15 +00001476 addr_case:
1477 return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
1478
1479 case JumpSupp:
1480 return (ekind == Err_Jump);
1481
1482 case FreeSupp:
1483 return (ekind == Err_Free || ekind == Err_FreeMismatch);
1484
1485 case OverlapSupp:
1486 return (ekind == Err_Overlap);
1487
1488 case LeakSupp:
philippe2193a7c2012-12-08 17:54:16 +00001489 if (ekind == Err_Leak) {
1490 MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
philippe4e32d672013-10-17 22:10:41 +00001491 if (lse->leak_search_gen != MC_(leak_search_gen)) {
1492 // First time we see this suppression during this leak search.
1493 // => reset the counters to 0.
1494 lse->blocks_suppressed = 0;
1495 lse->bytes_suppressed = 0;
1496 lse->leak_search_gen = MC_(leak_search_gen);
1497 }
philippe2193a7c2012-12-08 17:54:16 +00001498 return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
1499 } else
1500 return False;
sewardj7ce71662008-05-02 10:33:15 +00001501
1502 case MempoolSupp:
1503 return (ekind == Err_IllegalMempool);
1504
florian7b6899d2014-07-13 14:41:55 +00001505 case FishyValueSupp: {
1506 MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su);
1507
1508 return (ekind == Err_FishyValue) &&
1509 VG_STREQ(extra->Err.FishyValue.function_name,
1510 supp_extra->function_name) &&
1511 VG_STREQ(extra->Err.FishyValue.argument_name,
1512 supp_extra->argument_name);
1513 }
1514
sewardj7ce71662008-05-02 10:33:15 +00001515 default:
1516 VG_(printf)("Error:\n"
1517 " unknown suppression type %d\n",
1518 VG_(get_supp_kind)(su));
1519 VG_(tool_panic)("unknown suppression type in "
1520 "MC_(error_matches_suppression)");
1521 }
1522}
1523
florian8e3fbb52014-10-20 19:02:38 +00001524const HChar* MC_(get_error_name) ( const Error* err )
sewardj7ce71662008-05-02 10:33:15 +00001525{
1526 switch (VG_(get_error_kind)(err)) {
1527 case Err_RegParam: return "Param";
1528 case Err_MemParam: return "Param";
1529 case Err_User: return "User";
1530 case Err_FreeMismatch: return "Free";
1531 case Err_IllegalMempool: return "Mempool";
1532 case Err_Free: return "Free";
1533 case Err_Jump: return "Jump";
1534 case Err_CoreMem: return "CoreMem";
1535 case Err_Overlap: return "Overlap";
1536 case Err_Leak: return "Leak";
1537 case Err_Cond: return "Cond";
florian7b6899d2014-07-13 14:41:55 +00001538 case Err_FishyValue: return "FishyValue";
sewardj7ce71662008-05-02 10:33:15 +00001539 case Err_Addr: {
1540 MC_Error* extra = VG_(get_error_extra)(err);
1541 switch ( extra->Err.Addr.szB ) {
1542 case 1: return "Addr1";
1543 case 2: return "Addr2";
1544 case 4: return "Addr4";
1545 case 8: return "Addr8";
1546 case 16: return "Addr16";
rhyskidd9d83e992015-07-01 23:04:58 +00001547 case 32: return "Addr32";
sewardj7ce71662008-05-02 10:33:15 +00001548 default: VG_(tool_panic)("unexpected size for Addr");
1549 }
1550 }
1551 case Err_Value: {
1552 MC_Error* extra = VG_(get_error_extra)(err);
1553 switch ( extra->Err.Value.szB ) {
1554 case 1: return "Value1";
1555 case 2: return "Value2";
1556 case 4: return "Value4";
1557 case 8: return "Value8";
1558 case 16: return "Value16";
rhyskidd9d83e992015-07-01 23:04:58 +00001559 case 32: return "Value32";
sewardj7ce71662008-05-02 10:33:15 +00001560 default: VG_(tool_panic)("unexpected size for Value");
1561 }
1562 }
1563 default: VG_(tool_panic)("get_error_name: unexpected type");
1564 }
1565}
1566
florian8e3fbb52014-10-20 19:02:38 +00001567SizeT MC_(get_extra_suppression_info) ( const Error* err,
florian3e81b8b2014-10-07 14:28:52 +00001568 /*OUT*/HChar* buf, Int nBuf )
sewardj7ce71662008-05-02 10:33:15 +00001569{
Elliott Hughesa0664b92017-04-18 17:46:52 -07001570 ErrorKind ekind = VG_(get_error_kind)(err);
sewardj588adef2009-08-15 22:41:51 +00001571 tl_assert(buf);
florian3e81b8b2014-10-07 14:28:52 +00001572 tl_assert(nBuf >= 1);
1573
sewardj7ce71662008-05-02 10:33:15 +00001574 if (Err_RegParam == ekind || Err_MemParam == ekind) {
floriane543f302012-10-21 19:43:43 +00001575 const HChar* errstr = VG_(get_error_string)(err);
sewardj588adef2009-08-15 22:41:51 +00001576 tl_assert(errstr);
florian3e81b8b2014-10-07 14:28:52 +00001577 return VG_(snprintf)(buf, nBuf, "%s", errstr);
philippe2193a7c2012-12-08 17:54:16 +00001578 } else if (Err_Leak == ekind) {
1579 MC_Error* extra = VG_(get_error_extra)(err);
florian3e81b8b2014-10-07 14:28:52 +00001580 return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s",
philippe2193a7c2012-12-08 17:54:16 +00001581 pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state));
florian7b6899d2014-07-13 14:41:55 +00001582 } else if (Err_FishyValue == ekind) {
1583 MC_Error* extra = VG_(get_error_extra)(err);
florian3e81b8b2014-10-07 14:28:52 +00001584 return VG_(snprintf) (buf, nBuf, "%s(%s)",
1585 extra->Err.FishyValue.function_name,
1586 extra->Err.FishyValue.argument_name);
sewardj588adef2009-08-15 22:41:51 +00001587 } else {
florian3e81b8b2014-10-07 14:28:52 +00001588 buf[0] = '\0';
1589 return 0;
sewardj7ce71662008-05-02 10:33:15 +00001590 }
1591}
1592
florian8e3fbb52014-10-20 19:02:38 +00001593SizeT MC_(print_extra_suppression_use) ( const Supp *su,
florian3e81b8b2014-10-07 14:28:52 +00001594 /*OUT*/HChar *buf, Int nBuf )
philippe4e32d672013-10-17 22:10:41 +00001595{
florian3e81b8b2014-10-07 14:28:52 +00001596 tl_assert(nBuf >= 1);
1597
philippe4e32d672013-10-17 22:10:41 +00001598 if (VG_(get_supp_kind)(su) == LeakSupp) {
1599 MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1600
1601 if (lse->leak_search_gen == MC_(leak_search_gen)
1602 && lse->blocks_suppressed > 0) {
florian3e81b8b2014-10-07 14:28:52 +00001603 return VG_(snprintf) (buf, nBuf,
1604 "suppressed: %'lu bytes in %'lu blocks",
1605 lse->bytes_suppressed,
1606 lse->blocks_suppressed);
1607 }
1608 }
1609
1610 buf[0] = '\0';
1611 return 0;
philippe4e32d672013-10-17 22:10:41 +00001612}
1613
florian8e3fbb52014-10-20 19:02:38 +00001614void MC_(update_extra_suppression_use) ( const Error* err, const Supp* su)
philippe4e32d672013-10-17 22:10:41 +00001615{
1616 if (VG_(get_supp_kind)(su) == LeakSupp) {
1617 MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
1618 MC_Error* extra = VG_(get_error_extra)(err);
1619
philippee4200b52014-09-02 19:26:40 +00001620 tl_assert (lse->leak_search_gen == MC_(leak_search_gen));
philippe4e32d672013-10-17 22:10:41 +00001621 lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
1622 lse->bytes_suppressed
1623 += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
1624 }
1625}
sewardj7ce71662008-05-02 10:33:15 +00001626
1627/*--------------------------------------------------------------------*/
1628/*--- end mc_errors.c ---*/
1629/*--------------------------------------------------------------------*/