blob: 5084f2853dae4d30605bafac744963cae1748abe [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
sewardjec062e82011-10-23 07:32:08 +000011 Copyright (C) 2000-2011 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"
sewardj7ce71662008-05-02 10:33:15 +000047
48#include "mc_include.h"
sewardj7ce71662008-05-02 10:33:15 +000049
50
51/*------------------------------------------------------------*/
52/*--- Error types ---*/
53/*------------------------------------------------------------*/
54
55/* See comment in mc_include.h */
56Bool MC_(any_value_errors) = False;
57
58
59// Different kinds of blocks.
60typedef enum {
61 Block_Mallocd = 111,
62 Block_Freed,
63 Block_Mempool,
64 Block_MempoolChunk,
65 Block_UserG
66} BlockKind;
67
68/* ------------------ Addresses -------------------- */
69
70/* The classification of a faulting address. */
71typedef
72 enum {
73 Addr_Undescribed, // as-yet unclassified
74 Addr_Unknown, // classification yielded nothing useful
75 Addr_Block, // in malloc'd/free'd block
76 Addr_Stack, // on a thread's stack
77 Addr_DataSym, // in a global data sym
78 Addr_Variable, // variable described by the debug info
79 Addr_SectKind // last-ditch classification attempt
80 }
81 AddrTag;
82
83typedef
84 struct _AddrInfo
85 AddrInfo;
86
87struct _AddrInfo {
88 AddrTag tag;
89 union {
90 // As-yet unclassified.
91 struct { } Undescribed;
92
93 // On a stack.
94 struct {
95 ThreadId tid; // Which thread's stack?
96 } Stack;
97
98 // This covers heap blocks (normal and from mempools) and user-defined
99 // blocks.
100 struct {
101 BlockKind block_kind;
102 Char* block_desc; // "block", "mempool" or user-defined
103 SizeT block_szB;
njnc4431bf2009-01-15 21:29:24 +0000104 PtrdiffT rwoffset;
sewardj7ce71662008-05-02 10:33:15 +0000105 ExeContext* lastchange;
106 } Block;
107
njnc4431bf2009-01-15 21:29:24 +0000108 // In a global .data symbol. This holds the first 127 chars of
109 // the variable's name (zero terminated), plus a (memory) offset.
sewardj7ce71662008-05-02 10:33:15 +0000110 struct {
njnc4431bf2009-01-15 21:29:24 +0000111 Char name[128];
112 PtrdiffT offset;
sewardj7ce71662008-05-02 10:33:15 +0000113 } DataSym;
114
sewardj6b523cd2009-07-15 14:49:40 +0000115 // Is described by Dwarf debug info. XArray*s of HChar.
sewardj7ce71662008-05-02 10:33:15 +0000116 struct {
sewardj6b523cd2009-07-15 14:49:40 +0000117 XArray* /* of HChar */ descr1;
118 XArray* /* of HChar */ descr2;
sewardj7ce71662008-05-02 10:33:15 +0000119 } Variable;
120
121 // Could only narrow it down to be the PLT/GOT/etc of a given
122 // object. Better than nothing, perhaps.
123 struct {
124 Char objname[128];
125 VgSectKind kind;
126 } SectKind;
127
128 // Classification yielded nothing useful.
129 struct { } Unknown;
130
131 } Addr;
132};
133
134/* ------------------ Errors ----------------------- */
135
136/* What kind of error it is. */
137typedef
138 enum {
139 Err_Value,
140 Err_Cond,
141 Err_CoreMem,
142 Err_Addr,
143 Err_Jump,
144 Err_RegParam,
145 Err_MemParam,
146 Err_User,
147 Err_Free,
148 Err_FreeMismatch,
149 Err_Overlap,
150 Err_Leak,
151 Err_IllegalMempool,
152 }
153 MC_ErrorTag;
154
155
156typedef struct _MC_Error MC_Error;
157
158struct _MC_Error {
159 // Nb: we don't need the tag here, as it's stored in the Error type! Yuk.
160 //MC_ErrorTag tag;
161
162 union {
163 // Use of an undefined value:
164 // - as a pointer in a load or store
165 // - as a jump target
166 struct {
167 SizeT szB; // size of value in bytes
168 // Origin info
169 UInt otag; // origin tag
170 ExeContext* origin_ec; // filled in later
171 } Value;
172
173 // Use of an undefined value in a conditional branch or move.
174 struct {
175 // Origin info
176 UInt otag; // origin tag
177 ExeContext* origin_ec; // filled in later
178 } Cond;
179
180 // Addressability error in core (signal-handling) operation.
181 // It would be good to get rid of this error kind, merge it with
182 // another one somehow.
183 struct {
184 } CoreMem;
185
186 // Use of an unaddressable memory location in a load or store.
187 struct {
188 Bool isWrite; // read or write?
189 SizeT szB; // not used for exec (jump) errors
190 Bool maybe_gcc; // True if just below %esp -- could be a gcc bug
191 AddrInfo ai;
192 } Addr;
193
194 // Jump to an unaddressable memory location.
195 struct {
196 AddrInfo ai;
197 } Jump;
198
199 // System call register input contains undefined bytes.
200 struct {
201 // Origin info
202 UInt otag; // origin tag
203 ExeContext* origin_ec; // filled in later
204 } RegParam;
205
206 // System call memory input contains undefined/unaddressable bytes
207 struct {
208 Bool isAddrErr; // Addressability or definedness error?
209 AddrInfo ai;
210 // Origin info
211 UInt otag; // origin tag
212 ExeContext* origin_ec; // filled in later
213 } MemParam;
214
215 // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE.
216 struct {
217 Bool isAddrErr; // Addressability or definedness error?
218 AddrInfo ai;
219 // Origin info
220 UInt otag; // origin tag
221 ExeContext* origin_ec; // filled in later
222 } User;
223
224 // Program tried to free() something that's not a heap block (this
225 // covers double-frees). */
226 struct {
227 AddrInfo ai;
228 } Free;
229
230 // Program allocates heap block with one function
231 // (malloc/new/new[]/custom) and deallocates with not the matching one.
232 struct {
233 AddrInfo ai;
234 } FreeMismatch;
235
236 // Call to strcpy, memcpy, etc, with overlapping blocks.
237 struct {
238 Addr src; // Source block
239 Addr dst; // Destination block
240 Int szB; // Size in bytes; 0 if unused.
241 } Overlap;
242
243 // A memory leak.
244 struct {
245 UInt n_this_record;
246 UInt n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000247 LossRecord* lr;
sewardj7ce71662008-05-02 10:33:15 +0000248 } Leak;
249
250 // A memory pool error.
251 struct {
252 AddrInfo ai;
253 } IllegalMempool;
254
255 } Err;
256};
257
258
259/*------------------------------------------------------------*/
260/*--- Printing errors ---*/
261/*------------------------------------------------------------*/
262
sewardj6b523cd2009-07-15 14:49:40 +0000263/* This is the "this error is due to be printed shortly; so have a
264 look at it any print any preamble you want" function. Which, in
265 Memcheck, we don't use. Hence a no-op.
266*/
267void MC_(before_pp_Error) ( Error* err ) {
268}
269
270/* Do a printf-style operation on either the XML or normal output
271 channel, depending on the setting of VG_(clo_xml).
272*/
273static void emit_WRK ( HChar* format, va_list vargs )
274{
275 if (VG_(clo_xml)) {
276 VG_(vprintf_xml)(format, vargs);
277 } else {
278 VG_(vmessage)(Vg_UserMsg, format, vargs);
279 }
280}
281static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2);
282static void emit ( HChar* format, ... )
283{
284 va_list vargs;
285 va_start(vargs, format);
286 emit_WRK(format, vargs);
287 va_end(vargs);
288}
289static void emiN ( HChar* format, ... ) /* NO FORMAT CHECK */
290{
291 va_list vargs;
292 va_start(vargs, format);
293 emit_WRK(format, vargs);
294 va_end(vargs);
295}
296
297
sewardj7ce71662008-05-02 10:33:15 +0000298static void mc_pp_AddrInfo ( Addr a, AddrInfo* ai, Bool maybe_gcc )
299{
300 HChar* xpre = VG_(clo_xml) ? " <auxwhat>" : " ";
301 HChar* xpost = VG_(clo_xml) ? "</auxwhat>" : "";
302
303 switch (ai->tag) {
304 case Addr_Unknown:
305 if (maybe_gcc) {
sewardj6b523cd2009-07-15 14:49:40 +0000306 emit( "%sAddress 0x%llx is just below the stack ptr. "
307 "To suppress, use: --workaround-gcc296-bugs=yes%s\n",
308 xpre, (ULong)a, xpost );
sewardj7ce71662008-05-02 10:33:15 +0000309 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000310 emit( "%sAddress 0x%llx "
311 "is not stack'd, malloc'd or (recently) free'd%s\n",
312 xpre, (ULong)a, xpost );
sewardj7ce71662008-05-02 10:33:15 +0000313 }
314 break;
315
316 case Addr_Stack:
sewardj6b523cd2009-07-15 14:49:40 +0000317 emit( "%sAddress 0x%llx is on thread %d's stack%s\n",
318 xpre, (ULong)a, ai->Addr.Stack.tid, xpost );
sewardj7ce71662008-05-02 10:33:15 +0000319 break;
320
321 case Addr_Block: {
njnc4431bf2009-01-15 21:29:24 +0000322 SizeT block_szB = ai->Addr.Block.block_szB;
323 PtrdiffT rwoffset = ai->Addr.Block.rwoffset;
324 SizeT delta;
325 const Char* relative;
sewardj7ce71662008-05-02 10:33:15 +0000326
327 if (rwoffset < 0) {
328 delta = (SizeT)(-rwoffset);
329 relative = "before";
330 } else if (rwoffset >= block_szB) {
331 delta = rwoffset - block_szB;
332 relative = "after";
333 } else {
334 delta = rwoffset;
335 relative = "inside";
336 }
sewardj6b523cd2009-07-15 14:49:40 +0000337 emit(
338 "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n",
sewardj7ce71662008-05-02 10:33:15 +0000339 xpre,
340 a, delta, relative, ai->Addr.Block.block_desc,
341 block_szB,
342 ai->Addr.Block.block_kind==Block_Mallocd ? "alloc'd"
343 : ai->Addr.Block.block_kind==Block_Freed ? "free'd"
344 : "client-defined",
sewardj6b523cd2009-07-15 14:49:40 +0000345 xpost
346 );
sewardj7ce71662008-05-02 10:33:15 +0000347 VG_(pp_ExeContext)(ai->Addr.Block.lastchange);
348 break;
349 }
350
351 case Addr_DataSym:
sewardj6b523cd2009-07-15 14:49:40 +0000352 emiN( "%sAddress 0x%llx is %llu bytes "
bartb3af9cf2011-10-06 19:08:37 +0000353 "inside data symbol \"%pS\"%s\n",
sewardj6b523cd2009-07-15 14:49:40 +0000354 xpre,
355 (ULong)a,
356 (ULong)ai->Addr.DataSym.offset,
357 ai->Addr.DataSym.name,
358 xpost );
sewardj7ce71662008-05-02 10:33:15 +0000359 break;
360
361 case Addr_Variable:
sewardj6b523cd2009-07-15 14:49:40 +0000362 /* Note, no need for XML tags here, because descr1/2 will
363 already have <auxwhat> or <xauxwhat>s on them, in XML
364 mode. */
365 if (ai->Addr.Variable.descr1)
366 emit( "%s%s\n",
367 VG_(clo_xml) ? " " : " ",
368 (HChar*)VG_(indexXA)(ai->Addr.Variable.descr1, 0) );
369 if (ai->Addr.Variable.descr2)
370 emit( "%s%s\n",
371 VG_(clo_xml) ? " " : " ",
372 (HChar*)VG_(indexXA)(ai->Addr.Variable.descr2, 0) );
sewardj7ce71662008-05-02 10:33:15 +0000373 break;
374
375 case Addr_SectKind:
bartb3af9cf2011-10-06 19:08:37 +0000376 emiN( "%sAddress 0x%llx is in the %pS segment of %pS%s\n",
sewardj6b523cd2009-07-15 14:49:40 +0000377 xpre,
378 (ULong)a,
379 VG_(pp_SectKind)(ai->Addr.SectKind.kind),
380 ai->Addr.SectKind.objname,
381 xpost );
sewardj7ce71662008-05-02 10:33:15 +0000382 break;
383
384 default:
385 VG_(tool_panic)("mc_pp_AddrInfo");
386 }
387}
388
389static const HChar* str_leak_lossmode ( Reachedness lossmode )
390{
391 const HChar *loss = "?";
392 switch (lossmode) {
393 case Unreached: loss = "definitely lost"; break;
394 case IndirectLeak: loss = "indirectly lost"; break;
njn8225cc02009-03-09 22:52:24 +0000395 case Possible: loss = "possibly lost"; break;
396 case Reachable: loss = "still reachable"; break;
sewardj7ce71662008-05-02 10:33:15 +0000397 }
398 return loss;
399}
400
401static const HChar* xml_leak_kind ( Reachedness lossmode )
402{
403 const HChar *loss = "?";
404 switch (lossmode) {
405 case Unreached: loss = "Leak_DefinitelyLost"; break;
406 case IndirectLeak: loss = "Leak_IndirectlyLost"; break;
njn8225cc02009-03-09 22:52:24 +0000407 case Possible: loss = "Leak_PossiblyLost"; break;
408 case Reachable: loss = "Leak_StillReachable"; break;
sewardj7ce71662008-05-02 10:33:15 +0000409 }
410 return loss;
411}
412
sewardj7ce71662008-05-02 10:33:15 +0000413static void mc_pp_origin ( ExeContext* ec, UInt okind )
414{
sewardj6b523cd2009-07-15 14:49:40 +0000415 HChar* src = NULL;
sewardj7ce71662008-05-02 10:33:15 +0000416 tl_assert(ec);
417
418 switch (okind) {
419 case MC_OKIND_STACK: src = " by a stack allocation"; break;
420 case MC_OKIND_HEAP: src = " by a heap allocation"; break;
421 case MC_OKIND_USER: src = " by a client request"; break;
422 case MC_OKIND_UNKNOWN: src = ""; break;
423 }
424 tl_assert(src); /* guards against invalid 'okind' */
425
426 if (VG_(clo_xml)) {
sewardj6b523cd2009-07-15 14:49:40 +0000427 emit( " <auxwhat>Uninitialised value was created%s</auxwhat>\n",
428 src);
429 VG_(pp_ExeContext)( ec );
430 } else {
431 emit( " Uninitialised value was created%s\n", src);
432 VG_(pp_ExeContext)( ec );
sewardj7ce71662008-05-02 10:33:15 +0000433 }
434}
435
sewardjc8bd1df2011-06-26 12:41:33 +0000436char * MC_(snprintf_delta) (char * buf, Int size,
437 SizeT current_val, SizeT old_val,
438 LeakCheckDeltaMode delta_mode)
439{
440 if (delta_mode == LCD_Any)
441 buf[0] = '\0';
442 else if (current_val >= old_val)
443 VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val);
444 else
445 VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val);
446
447 return buf;
448}
449
philippea22f59d2012-01-26 23:13:52 +0000450static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
451 LossRecord* lr, Bool xml)
452{
453 // char arrays to produce the indication of increase/decrease in case
454 // of delta_mode != LCD_Any
455 char d_bytes[20];
456 char d_direct_bytes[20];
457 char d_indirect_bytes[20];
458 char d_num_blocks[20];
459
460 MC_(snprintf_delta) (d_bytes, 20,
461 lr->szB + lr->indirect_szB,
462 lr->old_szB + lr->old_indirect_szB,
463 MC_(detect_memory_leaks_last_delta_mode));
464 MC_(snprintf_delta) (d_direct_bytes, 20,
465 lr->szB,
466 lr->old_szB,
467 MC_(detect_memory_leaks_last_delta_mode));
468 MC_(snprintf_delta) (d_indirect_bytes, 20,
469 lr->indirect_szB,
470 lr->old_indirect_szB,
471 MC_(detect_memory_leaks_last_delta_mode));
472 MC_(snprintf_delta) (d_num_blocks, 20,
473 (SizeT) lr->num_blocks,
474 (SizeT) lr->old_num_blocks,
475 MC_(detect_memory_leaks_last_delta_mode));
476
477 if (xml) {
478 emit(" <kind>%s</kind>\n", xml_leak_kind(lr->key.state));
479 if (lr->indirect_szB > 0) {
480 emit( " <xwhat>\n" );
481 emit( " <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
482 "in %'u%s blocks"
483 " are %s in loss record %'u of %'u</text>\n",
484 lr->szB + lr->indirect_szB, d_bytes,
485 lr->szB, d_direct_bytes,
486 lr->indirect_szB, d_indirect_bytes,
487 lr->num_blocks, d_num_blocks,
488 str_leak_lossmode(lr->key.state),
489 n_this_record, n_total_records );
490 // Nb: don't put commas in these XML numbers
491 emit( " <leakedbytes>%lu</leakedbytes>\n",
492 lr->szB + lr->indirect_szB );
493 emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
494 emit( " </xwhat>\n" );
495 } else {
496 emit( " <xwhat>\n" );
497 emit( " <text>%'lu%s bytes in %'u%s blocks"
498 " are %s in loss record %'u of %'u</text>\n",
499 lr->szB, d_direct_bytes,
500 lr->num_blocks, d_num_blocks,
501 str_leak_lossmode(lr->key.state),
502 n_this_record, n_total_records );
503 emit( " <leakedbytes>%ld</leakedbytes>\n", lr->szB);
504 emit( " <leakedblocks>%d</leakedblocks>\n", lr->num_blocks);
505 emit( " </xwhat>\n" );
506 }
507 VG_(pp_ExeContext)(lr->key.allocated_at);
508 } else { /* ! if (xml) */
509 if (lr->indirect_szB > 0) {
510 emit(
511 "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
512 " are %s in loss record %'u of %'u\n",
513 lr->szB + lr->indirect_szB, d_bytes,
514 lr->szB, d_direct_bytes,
515 lr->indirect_szB, d_indirect_bytes,
516 lr->num_blocks, d_num_blocks,
517 str_leak_lossmode(lr->key.state),
518 n_this_record, n_total_records
519 );
520 } else {
521 emit(
522 "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
523 lr->szB, d_direct_bytes,
524 lr->num_blocks, d_num_blocks,
525 str_leak_lossmode(lr->key.state),
526 n_this_record, n_total_records
527 );
528 }
529 VG_(pp_ExeContext)(lr->key.allocated_at);
530 } /* if (xml) */
531}
532
533void MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records,
534 LossRecord* l)
535{
536 pp_LossRecord (n_this_record, n_total_records, l, /* xml */ False);
537}
538
sewardj7ce71662008-05-02 10:33:15 +0000539void MC_(pp_Error) ( Error* err )
540{
sewardj6b523cd2009-07-15 14:49:40 +0000541 const Bool xml = VG_(clo_xml); /* a shorthand */
sewardj7ce71662008-05-02 10:33:15 +0000542 MC_Error* extra = VG_(get_error_extra)(err);
543
544 switch (VG_(get_error_kind)(err)) {
sewardj6b523cd2009-07-15 14:49:40 +0000545 case Err_CoreMem:
sewardj7ce71662008-05-02 10:33:15 +0000546 /* What the hell *is* a CoreMemError? jrs 2005-May-18 */
547 /* As of 2006-Dec-14, it's caused by unaddressable bytes in a
548 signal handler frame. --njn */
sewardj6b523cd2009-07-15 14:49:40 +0000549 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
550 // the following code is untested. Bad.
551 if (xml) {
552 emit( " <kind>CoreMemError</kind>\n" );
bartb3af9cf2011-10-06 19:08:37 +0000553 emiN( " <what>%pS contains unaddressable byte(s)</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000554 VG_(get_error_string)(err));
555 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
556 } else {
557 emit( "%s contains unaddressable byte(s)\n",
558 VG_(get_error_string)(err));
559 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
560 }
sewardj7ce71662008-05-02 10:33:15 +0000561 break;
sewardj7ce71662008-05-02 10:33:15 +0000562
563 case Err_Value:
564 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000565 if (xml) {
566 emit( " <kind>UninitValue</kind>\n" );
567 emit( " <what>Use of uninitialised value of size %ld</what>\n",
568 extra->Err.Value.szB );
569 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
570 if (extra->Err.Value.origin_ec)
571 mc_pp_origin( extra->Err.Value.origin_ec,
572 extra->Err.Value.otag & 3 );
sewardj7ce71662008-05-02 10:33:15 +0000573 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000574 /* Could also show extra->Err.Cond.otag if debugging origin
575 tracking */
576 emit( "Use of uninitialised value of size %ld\n",
577 extra->Err.Value.szB );
578 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
579 if (extra->Err.Value.origin_ec)
580 mc_pp_origin( extra->Err.Value.origin_ec,
581 extra->Err.Value.otag & 3 );
sewardj7ce71662008-05-02 10:33:15 +0000582 }
sewardj7ce71662008-05-02 10:33:15 +0000583 break;
584
585 case Err_Cond:
586 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000587 if (xml) {
588 emit( " <kind>UninitCondition</kind>\n" );
589 emit( " <what>Conditional jump or move depends"
590 " on uninitialised value(s)</what>\n" );
591 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
592 if (extra->Err.Cond.origin_ec)
593 mc_pp_origin( extra->Err.Cond.origin_ec,
594 extra->Err.Cond.otag & 3 );
sewardj7ce71662008-05-02 10:33:15 +0000595 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000596 /* Could also show extra->Err.Cond.otag if debugging origin
597 tracking */
598 emit( "Conditional jump or move depends"
599 " on uninitialised value(s)\n" );
600 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
601 if (extra->Err.Cond.origin_ec)
602 mc_pp_origin( extra->Err.Cond.origin_ec,
603 extra->Err.Cond.otag & 3 );
sewardj7ce71662008-05-02 10:33:15 +0000604 }
sewardj7ce71662008-05-02 10:33:15 +0000605 break;
606
607 case Err_RegParam:
608 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000609 if (xml) {
610 emit( " <kind>SyscallParam</kind>\n" );
bartb3af9cf2011-10-06 19:08:37 +0000611 emiN( " <what>Syscall param %pS contains "
sewardj6b523cd2009-07-15 14:49:40 +0000612 "uninitialised byte(s)</what>\n",
613 VG_(get_error_string)(err) );
614 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
615 if (extra->Err.RegParam.origin_ec)
616 mc_pp_origin( extra->Err.RegParam.origin_ec,
617 extra->Err.RegParam.otag & 3 );
618 } else {
619 emit( "Syscall param %s contains uninitialised byte(s)\n",
620 VG_(get_error_string)(err) );
621 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
622 if (extra->Err.RegParam.origin_ec)
623 mc_pp_origin( extra->Err.RegParam.origin_ec,
624 extra->Err.RegParam.otag & 3 );
625 }
sewardj7ce71662008-05-02 10:33:15 +0000626 break;
627
628 case Err_MemParam:
629 if (!extra->Err.MemParam.isAddrErr)
630 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000631 if (xml) {
632 emit( " <kind>SyscallParam</kind>\n" );
bartb3af9cf2011-10-06 19:08:37 +0000633 emiN( " <what>Syscall param %pS points to %s byte(s)</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000634 VG_(get_error_string)(err),
635 extra->Err.MemParam.isAddrErr
636 ? "unaddressable" : "uninitialised" );
637 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
638 mc_pp_AddrInfo(VG_(get_error_address)(err),
639 &extra->Err.MemParam.ai, False);
640 if (extra->Err.MemParam.origin_ec
641 && !extra->Err.MemParam.isAddrErr)
642 mc_pp_origin( extra->Err.MemParam.origin_ec,
643 extra->Err.MemParam.otag & 3 );
644 } else {
645 emit( "Syscall param %s points to %s byte(s)\n",
646 VG_(get_error_string)(err),
647 extra->Err.MemParam.isAddrErr
648 ? "unaddressable" : "uninitialised" );
649 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
650 mc_pp_AddrInfo(VG_(get_error_address)(err),
651 &extra->Err.MemParam.ai, False);
652 if (extra->Err.MemParam.origin_ec
653 && !extra->Err.MemParam.isAddrErr)
654 mc_pp_origin( extra->Err.MemParam.origin_ec,
655 extra->Err.MemParam.otag & 3 );
656 }
sewardj7ce71662008-05-02 10:33:15 +0000657 break;
658
659 case Err_User:
660 if (!extra->Err.User.isAddrErr)
661 MC_(any_value_errors) = True;
sewardj6b523cd2009-07-15 14:49:40 +0000662 if (xml) {
663 emit( " <kind>ClientCheck</kind>\n" );
664 emit( " <what>%s byte(s) found "
665 "during client check request</what>\n",
666 extra->Err.User.isAddrErr
667 ? "Unaddressable" : "Uninitialised" );
668 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
669 mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
670 False);
671 if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
672 mc_pp_origin( extra->Err.User.origin_ec,
673 extra->Err.User.otag & 3 );
674 } else {
675 emit( "%s byte(s) found during client check request\n",
676 extra->Err.User.isAddrErr
677 ? "Unaddressable" : "Uninitialised" );
678 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
679 mc_pp_AddrInfo(VG_(get_error_address)(err), &extra->Err.User.ai,
680 False);
681 if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr)
682 mc_pp_origin( extra->Err.User.origin_ec,
683 extra->Err.User.otag & 3 );
684 }
sewardj7ce71662008-05-02 10:33:15 +0000685 break;
686
687 case Err_Free:
sewardj6b523cd2009-07-15 14:49:40 +0000688 if (xml) {
689 emit( " <kind>InvalidFree</kind>\n" );
bart91347382011-03-25 20:07:25 +0000690 emit( " <what>Invalid free() / delete / delete[]"
691 " / realloc()</what>\n" );
sewardj6b523cd2009-07-15 14:49:40 +0000692 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
693 mc_pp_AddrInfo( VG_(get_error_address)(err),
694 &extra->Err.Free.ai, False );
695 } else {
bart91347382011-03-25 20:07:25 +0000696 emit( "Invalid free() / delete / delete[] / realloc()\n" );
sewardj6b523cd2009-07-15 14:49:40 +0000697 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
698 mc_pp_AddrInfo( VG_(get_error_address)(err),
699 &extra->Err.Free.ai, False );
700 }
sewardj7ce71662008-05-02 10:33:15 +0000701 break;
702
703 case Err_FreeMismatch:
sewardj6b523cd2009-07-15 14:49:40 +0000704 if (xml) {
705 emit( " <kind>MismatchedFree</kind>\n" );
706 emit( " <what>Mismatched free() / delete / delete []</what>\n" );
707 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
708 mc_pp_AddrInfo(VG_(get_error_address)(err),
709 &extra->Err.FreeMismatch.ai, False);
710 } else {
711 emit( "Mismatched free() / delete / delete []\n" );
712 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
713 mc_pp_AddrInfo(VG_(get_error_address)(err),
714 &extra->Err.FreeMismatch.ai, False);
715 }
sewardj7ce71662008-05-02 10:33:15 +0000716 break;
717
718 case Err_Addr:
sewardj6b523cd2009-07-15 14:49:40 +0000719 if (xml) {
720 emit( " <kind>Invalid%s</kind>\n",
721 extra->Err.Addr.isWrite ? "Write" : "Read" );
722 emit( " <what>Invalid %s of size %ld</what>\n",
723 extra->Err.Addr.isWrite ? "write" : "read",
724 extra->Err.Addr.szB );
725 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
726 mc_pp_AddrInfo( VG_(get_error_address)(err),
727 &extra->Err.Addr.ai,
728 extra->Err.Addr.maybe_gcc );
sewardj7ce71662008-05-02 10:33:15 +0000729 } else {
sewardj6b523cd2009-07-15 14:49:40 +0000730 emit( "Invalid %s of size %ld\n",
731 extra->Err.Addr.isWrite ? "write" : "read",
732 extra->Err.Addr.szB );
733 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
734
735 mc_pp_AddrInfo( VG_(get_error_address)(err),
736 &extra->Err.Addr.ai,
737 extra->Err.Addr.maybe_gcc );
sewardj7ce71662008-05-02 10:33:15 +0000738 }
sewardj7ce71662008-05-02 10:33:15 +0000739 break;
740
741 case Err_Jump:
sewardj6b523cd2009-07-15 14:49:40 +0000742 if (xml) {
743 emit( " <kind>InvalidJump</kind>\n" );
744 emit( " <what>Jump to the invalid address stated "
745 "on the next line</what>\n" );
746 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
747 mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
748 False );
749 } else {
750 emit( "Jump to the invalid address stated on the next line\n" );
751 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
752 mc_pp_AddrInfo( VG_(get_error_address)(err), &extra->Err.Jump.ai,
753 False );
754 }
sewardj7ce71662008-05-02 10:33:15 +0000755 break;
756
757 case Err_Overlap:
sewardj6b523cd2009-07-15 14:49:40 +0000758 if (xml) {
759 emit( " <kind>Overlap</kind>\n" );
760 if (extra->Err.Overlap.szB == 0) {
761 emiN( " <what>Source and destination overlap "
bartb3af9cf2011-10-06 19:08:37 +0000762 "in %pS(%#lx, %#lx)\n</what>\n",
sewardj6b523cd2009-07-15 14:49:40 +0000763 VG_(get_error_string)(err),
764 extra->Err.Overlap.dst, extra->Err.Overlap.src );
765 } else {
766 emit( " <what>Source and destination overlap "
767 "in %s(%#lx, %#lx, %d)</what>\n",
768 VG_(get_error_string)(err),
769 extra->Err.Overlap.dst, extra->Err.Overlap.src,
770 extra->Err.Overlap.szB );
771 }
772 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
773 } else {
774 if (extra->Err.Overlap.szB == 0) {
bartb3af9cf2011-10-06 19:08:37 +0000775 emiN( "Source and destination overlap in %pS(%#lx, %#lx)\n",
sewardj6b523cd2009-07-15 14:49:40 +0000776 VG_(get_error_string)(err),
777 extra->Err.Overlap.dst, extra->Err.Overlap.src );
778 } else {
779 emit( "Source and destination overlap in %s(%#lx, %#lx, %d)\n",
780 VG_(get_error_string)(err),
781 extra->Err.Overlap.dst, extra->Err.Overlap.src,
782 extra->Err.Overlap.szB );
783 }
784 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
785 }
sewardj7ce71662008-05-02 10:33:15 +0000786 break;
787
788 case Err_IllegalMempool:
sewardj6b523cd2009-07-15 14:49:40 +0000789 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK
790 // the following code is untested. Bad.
791 if (xml) {
792 emit( " <kind>InvalidMemPool</kind>\n" );
793 emit( " <what>Illegal memory pool address</what>\n" );
794 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
795 mc_pp_AddrInfo( VG_(get_error_address)(err),
796 &extra->Err.IllegalMempool.ai, False );
797 } else {
798 emit( "Illegal memory pool address\n" );
799 VG_(pp_ExeContext)( VG_(get_error_where)(err) );
800 mc_pp_AddrInfo( VG_(get_error_address)(err),
801 &extra->Err.IllegalMempool.ai, False );
802 }
sewardj7ce71662008-05-02 10:33:15 +0000803 break;
804
805 case Err_Leak: {
sewardj7ce71662008-05-02 10:33:15 +0000806 UInt n_this_record = extra->Err.Leak.n_this_record;
807 UInt n_total_records = extra->Err.Leak.n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000808 LossRecord* lr = extra->Err.Leak.lr;
philippea22f59d2012-01-26 23:13:52 +0000809 pp_LossRecord (n_this_record, n_total_records, lr, xml);
sewardj7ce71662008-05-02 10:33:15 +0000810 break;
811 }
812
813 default:
814 VG_(printf)("Error:\n unknown Memcheck error code %d\n",
815 VG_(get_error_kind)(err));
816 VG_(tool_panic)("unknown error code in mc_pp_Error)");
817 }
818}
819
820/*------------------------------------------------------------*/
821/*--- Recording errors ---*/
822/*------------------------------------------------------------*/
823
824/* These many bytes below %ESP are considered addressible if we're
825 doing the --workaround-gcc296-bugs hack. */
826#define VG_GCC296_BUG_STACK_SLOP 1024
827
828/* Is this address within some small distance below %ESP? Used only
829 for the --workaround-gcc296-bugs kludge. */
830static Bool is_just_below_ESP( Addr esp, Addr aa )
831{
sewardj7d751b22010-07-21 12:46:44 +0000832 esp -= VG_STACK_REDZONE_SZB;
sewardj7ce71662008-05-02 10:33:15 +0000833 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP)
834 return True;
835 else
836 return False;
837}
838
839/* --- Called from generated and non-generated code --- */
840
841void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB,
842 Bool isWrite )
843{
844 MC_Error extra;
845 Bool just_below_esp;
846
847 if (MC_(in_ignored_range)(a))
848 return;
849
sewardj3b290482011-05-06 21:02:55 +0000850 if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB))
851 return;
852
sewardj7ce71662008-05-02 10:33:15 +0000853 just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
854
855 /* If this is caused by an access immediately below %ESP, and the
856 user asks nicely, we just ignore it. */
857 if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
858 return;
859
860 extra.Err.Addr.isWrite = isWrite;
861 extra.Err.Addr.szB = szB;
862 extra.Err.Addr.maybe_gcc = just_below_esp;
863 extra.Err.Addr.ai.tag = Addr_Undescribed;
864 VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
865}
866
867void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
868{
869 MC_Error extra;
870 tl_assert( MC_(clo_mc_level) >= 2 );
871 if (otag > 0)
872 tl_assert( MC_(clo_mc_level) == 3 );
873 extra.Err.Value.szB = szB;
874 extra.Err.Value.otag = otag;
875 extra.Err.Value.origin_ec = NULL; /* Filled in later */
876 VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
877}
878
879void MC_(record_cond_error) ( ThreadId tid, UInt otag )
880{
881 MC_Error extra;
882 tl_assert( MC_(clo_mc_level) >= 2 );
883 if (otag > 0)
884 tl_assert( MC_(clo_mc_level) == 3 );
885 extra.Err.Cond.otag = otag;
886 extra.Err.Cond.origin_ec = NULL; /* Filled in later */
887 VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
888}
889
890/* --- Called from non-generated code --- */
891
njn1dcee092009-02-24 03:07:37 +0000892/* This is for memory errors in signal-related memory. */
893void MC_(record_core_mem_error) ( ThreadId tid, Char* msg )
sewardj7ce71662008-05-02 10:33:15 +0000894{
895 VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
896}
897
898void MC_(record_regparam_error) ( ThreadId tid, Char* msg, UInt otag )
899{
900 MC_Error extra;
901 tl_assert(VG_INVALID_THREADID != tid);
902 if (otag > 0)
903 tl_assert( MC_(clo_mc_level) == 3 );
904 extra.Err.RegParam.otag = otag;
905 extra.Err.RegParam.origin_ec = NULL; /* Filled in later */
906 VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
907}
908
909void MC_(record_memparam_error) ( ThreadId tid, Addr a,
910 Bool isAddrErr, Char* msg, UInt otag )
911{
912 MC_Error extra;
913 tl_assert(VG_INVALID_THREADID != tid);
914 if (!isAddrErr)
915 tl_assert( MC_(clo_mc_level) >= 2 );
916 if (otag != 0) {
917 tl_assert( MC_(clo_mc_level) == 3 );
918 tl_assert( !isAddrErr );
919 }
920 extra.Err.MemParam.isAddrErr = isAddrErr;
921 extra.Err.MemParam.ai.tag = Addr_Undescribed;
922 extra.Err.MemParam.otag = otag;
923 extra.Err.MemParam.origin_ec = NULL; /* Filled in later */
924 VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
925}
926
927void MC_(record_jump_error) ( ThreadId tid, Addr a )
928{
929 MC_Error extra;
930 tl_assert(VG_INVALID_THREADID != tid);
931 extra.Err.Jump.ai.tag = Addr_Undescribed;
932 VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
933}
934
935void MC_(record_free_error) ( ThreadId tid, Addr a )
936{
937 MC_Error extra;
938 tl_assert(VG_INVALID_THREADID != tid);
939 extra.Err.Free.ai.tag = Addr_Undescribed;
940 VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
941}
942
943void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
944{
945 MC_Error extra;
946 AddrInfo* ai = &extra.Err.FreeMismatch.ai;
947 tl_assert(VG_INVALID_THREADID != tid);
948 ai->tag = Addr_Block;
949 ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed'
950 ai->Addr.Block.block_desc = "block";
951 ai->Addr.Block.block_szB = mc->szB;
952 ai->Addr.Block.rwoffset = 0;
953 ai->Addr.Block.lastchange = mc->where;
954 VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
955 &extra );
956}
957
958void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
959{
960 MC_Error extra;
961 tl_assert(VG_INVALID_THREADID != tid);
962 extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
963 VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
964}
965
966void MC_(record_overlap_error) ( ThreadId tid, Char* function,
967 Addr src, Addr dst, SizeT szB )
968{
969 MC_Error extra;
970 tl_assert(VG_INVALID_THREADID != tid);
971 extra.Err.Overlap.src = src;
972 extra.Err.Overlap.dst = dst;
973 extra.Err.Overlap.szB = szB;
974 VG_(maybe_record_error)(
975 tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
976}
977
978Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
njnb7a4e2e2009-05-01 00:30:43 +0000979 UInt n_total_records, LossRecord* lr,
njn18afe5d2009-08-10 08:25:39 +0000980 Bool print_record, Bool count_error )
sewardj7ce71662008-05-02 10:33:15 +0000981{
982 MC_Error extra;
983 extra.Err.Leak.n_this_record = n_this_record;
984 extra.Err.Leak.n_total_records = n_total_records;
njnb7a4e2e2009-05-01 00:30:43 +0000985 extra.Err.Leak.lr = lr;
sewardj7ce71662008-05-02 10:33:15 +0000986 return
987 VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
njn29a5c012009-05-06 06:15:55 +0000988 lr->key.allocated_at, print_record,
njn18afe5d2009-08-10 08:25:39 +0000989 /*allow_GDB_attach*/False, count_error );
sewardj7ce71662008-05-02 10:33:15 +0000990}
991
992void MC_(record_user_error) ( ThreadId tid, Addr a,
993 Bool isAddrErr, UInt otag )
994{
995 MC_Error extra;
996 if (otag != 0) {
997 tl_assert(!isAddrErr);
998 tl_assert( MC_(clo_mc_level) == 3 );
999 }
1000 if (!isAddrErr) {
1001 tl_assert( MC_(clo_mc_level) >= 2 );
1002 }
1003 tl_assert(VG_INVALID_THREADID != tid);
1004 extra.Err.User.isAddrErr = isAddrErr;
1005 extra.Err.User.ai.tag = Addr_Undescribed;
1006 extra.Err.User.otag = otag;
1007 extra.Err.User.origin_ec = NULL; /* Filled in later */
1008 VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
1009}
1010
1011/*------------------------------------------------------------*/
1012/*--- Other error operations ---*/
1013/*------------------------------------------------------------*/
1014
1015/* Compare error contexts, to detect duplicates. Note that if they
1016 are otherwise the same, the faulting addrs and associated rwoffsets
1017 are allowed to be different. */
1018Bool MC_(eq_Error) ( VgRes res, Error* e1, Error* e2 )
1019{
1020 MC_Error* extra1 = VG_(get_error_extra)(e1);
1021 MC_Error* extra2 = VG_(get_error_extra)(e2);
1022
1023 /* Guaranteed by calling function */
1024 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
1025
1026 switch (VG_(get_error_kind)(e1)) {
1027 case Err_CoreMem: {
1028 Char *e1s, *e2s;
1029 e1s = VG_(get_error_string)(e1);
1030 e2s = VG_(get_error_string)(e2);
1031 if (e1s == e2s) return True;
1032 if (VG_STREQ(e1s, e2s)) return True;
1033 return False;
1034 }
1035
1036 case Err_RegParam:
1037 return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
1038
1039 // Perhaps we should also check the addrinfo.akinds for equality.
1040 // That would result in more error reports, but only in cases where
1041 // a register contains uninitialised bytes and points to memory
1042 // containing uninitialised bytes. Currently, the 2nd of those to be
1043 // detected won't be reported. That is (nearly?) always the memory
1044 // error, which is good.
1045 case Err_MemParam:
1046 if (!VG_STREQ(VG_(get_error_string)(e1),
1047 VG_(get_error_string)(e2))) return False;
1048 // fall through
1049 case Err_User:
1050 return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
1051 ? True : False );
1052
1053 case Err_Free:
1054 case Err_FreeMismatch:
1055 case Err_Jump:
1056 case Err_IllegalMempool:
1057 case Err_Overlap:
1058 case Err_Cond:
1059 return True;
1060
1061 case Err_Addr:
1062 return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
1063 ? True : False );
1064
1065 case Err_Value:
1066 return ( extra1->Err.Value.szB == extra2->Err.Value.szB
1067 ? True : False );
1068
1069 case Err_Leak:
1070 VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
1071 "since it's handled with VG_(unique_error)()!");
1072
1073 default:
1074 VG_(printf)("Error:\n unknown error code %d\n",
1075 VG_(get_error_kind)(e1));
1076 VG_(tool_panic)("unknown error code in mc_eq_Error");
1077 }
1078}
1079
sewardj62b91042011-01-23 20:45:53 +00001080/* Functions used when searching MC_Chunk lists */
1081static
1082Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
sewardj7ce71662008-05-02 10:33:15 +00001083{
sewardj7ce71662008-05-02 10:33:15 +00001084 return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1085 MC_MALLOC_REDZONE_SZB );
1086}
sewardj62b91042011-01-23 20:45:53 +00001087static
1088Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
1089{
1090 return VG_(addr_is_in_block)( a, mc->data, mc->szB,
1091 rzB );
1092}
sewardj7ce71662008-05-02 10:33:15 +00001093
sewardj62b91042011-01-23 20:45:53 +00001094// Forward declarations
sewardj7ce71662008-05-02 10:33:15 +00001095static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
sewardj62b91042011-01-23 20:45:53 +00001096static Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
sewardj7ce71662008-05-02 10:33:15 +00001097
1098
1099/* Describe an address as best you can, for error messages,
1100 putting the result in ai. */
1101static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
1102{
1103 MC_Chunk* mc;
1104 ThreadId tid;
1105 Addr stack_min, stack_max;
1106 VgSectKind sect;
1107
1108 tl_assert(Addr_Undescribed == ai->tag);
1109
sewardj62b91042011-01-23 20:45:53 +00001110 /* -- Perhaps it's a user-named block? -- */
sewardj7ce71662008-05-02 10:33:15 +00001111 if (client_block_maybe_describe( a, ai )) {
1112 return;
1113 }
sewardj62b91042011-01-23 20:45:53 +00001114 /* -- Perhaps it's in mempool block? -- */
1115 if (mempool_block_maybe_describe( a, ai )) {
1116 return;
1117 }
philippe11cc9ce2012-03-11 17:59:00 +00001118 /* Blocks allocated by memcheck malloc functions are either
1119 on the recently freed list or on the malloc-ed list.
1120 Custom blocks can be on both : a recently freed block might
1121 have been just re-allocated.
1122 So, first search the malloc-ed block, as the most recent
1123 block is the probable cause of error.
1124 We however detect and report that this is a recently re-allocated
1125 block. */
1126 /* -- Search for a currently malloc'd block which might bracket it. -- */
1127 VG_(HT_ResetIter)(MC_(malloc_list));
1128 while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
1129 if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
1130 ai->tag = Addr_Block;
1131 ai->Addr.Block.block_kind = Block_Mallocd;
1132 if (MC_(get_freed_block_bracketting)( a ))
1133 ai->Addr.Block.block_desc = "recently re-allocated block";
1134 else
1135 ai->Addr.Block.block_desc = "block";
1136 ai->Addr.Block.block_szB = mc->szB;
1137 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
1138 ai->Addr.Block.lastchange = mc->where;
1139 return;
1140 }
1141 }
sewardj6b523cd2009-07-15 14:49:40 +00001142 /* -- Search for a recently freed block which might bracket it. -- */
sewardj403d8aa2011-10-22 19:48:57 +00001143 mc = MC_(get_freed_block_bracketting)( a );
1144 if (mc) {
1145 ai->tag = Addr_Block;
1146 ai->Addr.Block.block_kind = Block_Freed;
1147 ai->Addr.Block.block_desc = "block";
1148 ai->Addr.Block.block_szB = mc->szB;
1149 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
1150 ai->Addr.Block.lastchange = mc->where;
1151 return;
sewardj7ce71662008-05-02 10:33:15 +00001152 }
sewardj6b523cd2009-07-15 14:49:40 +00001153 /* -- Perhaps the variable type/location data describes it? -- */
1154 ai->Addr.Variable.descr1
1155 = VG_(newXA)( VG_(malloc), "mc.da.descr1",
1156 VG_(free), sizeof(HChar) );
1157 ai->Addr.Variable.descr2
1158 = VG_(newXA)( VG_(malloc), "mc.da.descr2",
1159 VG_(free), sizeof(HChar) );
1160
1161 (void) VG_(get_data_description)( ai->Addr.Variable.descr1,
1162 ai->Addr.Variable.descr2, a );
1163 /* If there's nothing in descr1/2, free them. Why is it safe to to
1164 VG_(indexXA) at zero here? Because VG_(get_data_description)
1165 guarantees to zero terminate descr1/2 regardless of the outcome
1166 of the call. So there's always at least one element in each XA
1167 after the call.
1168 */
1169 if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr1, 0 ))) {
1170 VG_(deleteXA)( ai->Addr.Variable.descr1 );
1171 ai->Addr.Variable.descr1 = NULL;
1172 }
1173 if (0 == VG_(strlen)( VG_(indexXA)( ai->Addr.Variable.descr2, 0 ))) {
1174 VG_(deleteXA)( ai->Addr.Variable.descr2 );
1175 ai->Addr.Variable.descr2 = NULL;
1176 }
1177 /* Assume (assert) that VG_(get_data_description) fills in descr1
1178 before it fills in descr2 */
1179 if (ai->Addr.Variable.descr1 == NULL)
1180 tl_assert(ai->Addr.Variable.descr2 == NULL);
1181 /* So did we get lucky? */
1182 if (ai->Addr.Variable.descr1 != NULL) {
sewardj7ce71662008-05-02 10:33:15 +00001183 ai->tag = Addr_Variable;
sewardj7ce71662008-05-02 10:33:15 +00001184 return;
1185 }
sewardj6b523cd2009-07-15 14:49:40 +00001186 /* -- Have a look at the low level data symbols - perhaps it's in
1187 there. -- */
sewardj7ce71662008-05-02 10:33:15 +00001188 VG_(memset)( &ai->Addr.DataSym.name,
1189 0, sizeof(ai->Addr.DataSym.name));
1190 if (VG_(get_datasym_and_offset)(
1191 a, &ai->Addr.DataSym.name[0],
1192 sizeof(ai->Addr.DataSym.name)-1,
1193 &ai->Addr.DataSym.offset )) {
1194 ai->tag = Addr_DataSym;
1195 tl_assert( ai->Addr.DataSym.name
1196 [ sizeof(ai->Addr.DataSym.name)-1 ] == 0);
1197 return;
1198 }
sewardj6b523cd2009-07-15 14:49:40 +00001199 /* -- Perhaps it's on a thread's stack? -- */
sewardj7ce71662008-05-02 10:33:15 +00001200 VG_(thread_stack_reset_iter)(&tid);
1201 while ( VG_(thread_stack_next)(&tid, &stack_min, &stack_max) ) {
1202 if (stack_min - VG_STACK_REDZONE_SZB <= a && a <= stack_max) {
1203 ai->tag = Addr_Stack;
1204 ai->Addr.Stack.tid = tid;
1205 return;
1206 }
1207 }
sewardj6b523cd2009-07-15 14:49:40 +00001208 /* -- last ditch attempt at classification -- */
sewardj7ce71662008-05-02 10:33:15 +00001209 tl_assert( sizeof(ai->Addr.SectKind.objname) > 4 );
1210 VG_(memset)( &ai->Addr.SectKind.objname,
1211 0, sizeof(ai->Addr.SectKind.objname));
1212 VG_(strcpy)( ai->Addr.SectKind.objname, "???" );
sewardje3f1e592009-07-31 09:41:29 +00001213 sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0],
1214 sizeof(ai->Addr.SectKind.objname)-1, a);
sewardj7ce71662008-05-02 10:33:15 +00001215 if (sect != Vg_SectUnknown) {
1216 ai->tag = Addr_SectKind;
1217 ai->Addr.SectKind.kind = sect;
1218 tl_assert( ai->Addr.SectKind.objname
1219 [ sizeof(ai->Addr.SectKind.objname)-1 ] == 0);
1220 return;
1221 }
sewardj6b523cd2009-07-15 14:49:40 +00001222 /* -- Clueless ... -- */
sewardj7ce71662008-05-02 10:33:15 +00001223 ai->tag = Addr_Unknown;
1224 return;
1225}
1226
sewardj3b290482011-05-06 21:02:55 +00001227void MC_(pp_describe_addr) ( Addr a )
1228{
1229 AddrInfo ai;
1230
1231 ai.tag = Addr_Undescribed;
1232 describe_addr (a, &ai);
1233 mc_pp_AddrInfo (a, &ai, /* maybe_gcc */ False);
1234}
1235
sewardj7ce71662008-05-02 10:33:15 +00001236/* Fill in *origin_ec as specified by otag, or NULL it out if otag
1237 does not refer to a known origin. */
1238static void update_origin ( /*OUT*/ExeContext** origin_ec,
1239 UInt otag )
1240{
1241 UInt ecu = otag & ~3;
1242 *origin_ec = NULL;
1243 if (VG_(is_plausible_ECU)(ecu)) {
1244 *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
1245 }
1246}
1247
1248/* Updates the copy with address info if necessary (but not for all errors). */
1249UInt MC_(update_Error_extra)( Error* err )
1250{
1251 MC_Error* extra = VG_(get_error_extra)(err);
1252
1253 switch (VG_(get_error_kind)(err)) {
1254 // These ones don't have addresses associated with them, and so don't
1255 // need any updating.
1256 case Err_CoreMem:
1257 //case Err_Value:
1258 //case Err_Cond:
1259 case Err_Overlap:
1260 // For Err_Leaks the returned size does not matter -- they are always
1261 // shown with VG_(unique_error)() so they 'extra' not copied. But
1262 // we make it consistent with the others.
1263 case Err_Leak:
1264 return sizeof(MC_Error);
1265
1266 // For value errors, get the ExeContext corresponding to the
1267 // origin tag. Note that it is a kludge to assume that
1268 // a length-1 trace indicates a stack origin. FIXME.
1269 case Err_Value:
1270 update_origin( &extra->Err.Value.origin_ec,
1271 extra->Err.Value.otag );
1272 return sizeof(MC_Error);
1273 case Err_Cond:
1274 update_origin( &extra->Err.Cond.origin_ec,
1275 extra->Err.Cond.otag );
1276 return sizeof(MC_Error);
1277 case Err_RegParam:
1278 update_origin( &extra->Err.RegParam.origin_ec,
1279 extra->Err.RegParam.otag );
1280 return sizeof(MC_Error);
1281
1282 // These ones always involve a memory address.
1283 case Err_Addr:
1284 describe_addr ( VG_(get_error_address)(err),
1285 &extra->Err.Addr.ai );
1286 return sizeof(MC_Error);
1287 case Err_MemParam:
1288 describe_addr ( VG_(get_error_address)(err),
1289 &extra->Err.MemParam.ai );
1290 update_origin( &extra->Err.MemParam.origin_ec,
1291 extra->Err.MemParam.otag );
1292 return sizeof(MC_Error);
1293 case Err_Jump:
1294 describe_addr ( VG_(get_error_address)(err),
1295 &extra->Err.Jump.ai );
1296 return sizeof(MC_Error);
1297 case Err_User:
1298 describe_addr ( VG_(get_error_address)(err),
1299 &extra->Err.User.ai );
1300 update_origin( &extra->Err.User.origin_ec,
1301 extra->Err.User.otag );
1302 return sizeof(MC_Error);
1303 case Err_Free:
1304 describe_addr ( VG_(get_error_address)(err),
1305 &extra->Err.Free.ai );
1306 return sizeof(MC_Error);
1307 case Err_IllegalMempool:
1308 describe_addr ( VG_(get_error_address)(err),
1309 &extra->Err.IllegalMempool.ai );
1310 return sizeof(MC_Error);
1311
1312 // Err_FreeMismatches have already had their address described; this is
1313 // possible because we have the MC_Chunk on hand when the error is
1314 // detected. However, the address may be part of a user block, and if so
1315 // we override the pre-determined description with a user block one.
1316 case Err_FreeMismatch: {
1317 tl_assert(extra && Block_Mallocd ==
1318 extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
1319 (void)client_block_maybe_describe( VG_(get_error_address)(err),
1320 &extra->Err.FreeMismatch.ai );
1321 return sizeof(MC_Error);
1322 }
1323
1324 default: VG_(tool_panic)("mc_update_extra: bad errkind");
1325 }
1326}
1327
sewardj62b91042011-01-23 20:45:53 +00001328
sewardj7ce71662008-05-02 10:33:15 +00001329static Bool client_block_maybe_describe( Addr a,
1330 /*OUT*/AddrInfo* ai )
1331{
sewardj56adc352008-05-02 11:25:17 +00001332 UWord i;
sewardj7ce71662008-05-02 10:33:15 +00001333 CGenBlock* cgbs = NULL;
1334 UWord cgb_used = 0;
sewardj56adc352008-05-02 11:25:17 +00001335
sewardj7ce71662008-05-02 10:33:15 +00001336 MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
1337 if (cgbs == NULL)
1338 tl_assert(cgb_used == 0);
1339
1340 /* Perhaps it's a general block ? */
1341 for (i = 0; i < cgb_used; i++) {
1342 if (cgbs[i].start == 0 && cgbs[i].size == 0)
1343 continue;
1344 // Use zero as the redzone for client blocks.
1345 if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
sewardj7ce71662008-05-02 10:33:15 +00001346 ai->tag = Addr_Block;
1347 ai->Addr.Block.block_kind = Block_UserG;
1348 ai->Addr.Block.block_desc = cgbs[i].desc;
1349 ai->Addr.Block.block_szB = cgbs[i].size;
sewardj56adc352008-05-02 11:25:17 +00001350 ai->Addr.Block.rwoffset = (Word)(a) - (Word)(cgbs[i].start);
sewardj7ce71662008-05-02 10:33:15 +00001351 ai->Addr.Block.lastchange = cgbs[i].where;
1352 return True;
1353 }
1354 }
1355 return False;
1356}
1357
1358
sewardj62b91042011-01-23 20:45:53 +00001359static Bool mempool_block_maybe_describe( Addr a,
1360 /*OUT*/AddrInfo* ai )
1361{
1362 MC_Mempool* mp;
1363 tl_assert( MC_(mempool_list) );
1364
1365 VG_(HT_ResetIter)( MC_(mempool_list) );
1366 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
1367 if (mp->chunks != NULL) {
1368 MC_Chunk* mc;
1369 VG_(HT_ResetIter)(mp->chunks);
1370 while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
1371 if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
1372 ai->tag = Addr_Block;
1373 ai->Addr.Block.block_kind = Block_MempoolChunk;
1374 ai->Addr.Block.block_desc = "block";
1375 ai->Addr.Block.block_szB = mc->szB;
1376 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data;
1377 ai->Addr.Block.lastchange = mc->where;
1378 return True;
1379 }
1380 }
1381 }
1382 }
1383 return False;
1384}
1385
1386
sewardj7ce71662008-05-02 10:33:15 +00001387/*------------------------------------------------------------*/
1388/*--- Suppressions ---*/
1389/*------------------------------------------------------------*/
1390
1391typedef
1392 enum {
1393 ParamSupp, // Bad syscall params
1394 UserSupp, // Errors arising from client-request checks
1395 CoreMemSupp, // Memory errors in core (pthread ops, signal handling)
1396
1397 // Undefined value errors of given size
1398 Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp,
1399
1400 // Undefined value error in conditional.
1401 CondSupp,
1402
1403 // Unaddressable read/write attempt at given size
1404 Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp,
1405
1406 JumpSupp, // Jump to unaddressable target
1407 FreeSupp, // Invalid or mismatching free
1408 OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc
1409 LeakSupp, // Something to be suppressed in a leak check.
1410 MempoolSupp, // Memory pool suppression.
1411 }
1412 MC_SuppKind;
1413
1414Bool MC_(is_recognised_suppression) ( Char* name, Supp* su )
1415{
1416 SuppKind skind;
1417
1418 if (VG_STREQ(name, "Param")) skind = ParamSupp;
1419 else if (VG_STREQ(name, "User")) skind = UserSupp;
1420 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
1421 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp;
1422 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp;
1423 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp;
1424 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp;
1425 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp;
1426 else if (VG_STREQ(name, "Jump")) skind = JumpSupp;
1427 else if (VG_STREQ(name, "Free")) skind = FreeSupp;
1428 else if (VG_STREQ(name, "Leak")) skind = LeakSupp;
1429 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
1430 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
1431 else if (VG_STREQ(name, "Cond")) skind = CondSupp;
1432 else if (VG_STREQ(name, "Value0")) skind = CondSupp; /* backwards compat */
1433 else if (VG_STREQ(name, "Value1")) skind = Value1Supp;
1434 else if (VG_STREQ(name, "Value2")) skind = Value2Supp;
1435 else if (VG_STREQ(name, "Value4")) skind = Value4Supp;
1436 else if (VG_STREQ(name, "Value8")) skind = Value8Supp;
1437 else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
1438 else
1439 return False;
1440
1441 VG_(set_supp_kind)(su, skind);
1442 return True;
1443}
1444
njn35db56c2009-07-24 07:38:29 +00001445Bool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp,
1446 SizeT* nBufp, Supp *su )
sewardj7ce71662008-05-02 10:33:15 +00001447{
1448 Bool eof;
1449
1450 if (VG_(get_supp_kind)(su) == ParamSupp) {
bart050eec52009-07-27 12:03:03 +00001451 eof = VG_(get_line) ( fd, bufpp, nBufp, NULL );
sewardj7ce71662008-05-02 10:33:15 +00001452 if (eof) return False;
njn35db56c2009-07-24 07:38:29 +00001453 VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
sewardj7ce71662008-05-02 10:33:15 +00001454 }
1455 return True;
1456}
1457
1458Bool MC_(error_matches_suppression) ( Error* err, Supp* su )
1459{
1460 Int su_szB;
1461 MC_Error* extra = VG_(get_error_extra)(err);
1462 ErrorKind ekind = VG_(get_error_kind )(err);
1463
1464 switch (VG_(get_supp_kind)(su)) {
1465 case ParamSupp:
1466 return ((ekind == Err_RegParam || ekind == Err_MemParam)
1467 && VG_STREQ(VG_(get_error_string)(err),
1468 VG_(get_supp_string)(su)));
1469
1470 case UserSupp:
1471 return (ekind == Err_User);
1472
1473 case CoreMemSupp:
1474 return (ekind == Err_CoreMem
1475 && VG_STREQ(VG_(get_error_string)(err),
1476 VG_(get_supp_string)(su)));
1477
1478 case Value1Supp: su_szB = 1; goto value_case;
1479 case Value2Supp: su_szB = 2; goto value_case;
1480 case Value4Supp: su_szB = 4; goto value_case;
1481 case Value8Supp: su_szB = 8; goto value_case;
1482 case Value16Supp:su_szB =16; goto value_case;
1483 value_case:
1484 return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
1485
1486 case CondSupp:
1487 return (ekind == Err_Cond);
1488
1489 case Addr1Supp: su_szB = 1; goto addr_case;
1490 case Addr2Supp: su_szB = 2; goto addr_case;
1491 case Addr4Supp: su_szB = 4; goto addr_case;
1492 case Addr8Supp: su_szB = 8; goto addr_case;
1493 case Addr16Supp:su_szB =16; goto addr_case;
1494 addr_case:
1495 return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
1496
1497 case JumpSupp:
1498 return (ekind == Err_Jump);
1499
1500 case FreeSupp:
1501 return (ekind == Err_Free || ekind == Err_FreeMismatch);
1502
1503 case OverlapSupp:
1504 return (ekind == Err_Overlap);
1505
1506 case LeakSupp:
1507 return (ekind == Err_Leak);
1508
1509 case MempoolSupp:
1510 return (ekind == Err_IllegalMempool);
1511
1512 default:
1513 VG_(printf)("Error:\n"
1514 " unknown suppression type %d\n",
1515 VG_(get_supp_kind)(su));
1516 VG_(tool_panic)("unknown suppression type in "
1517 "MC_(error_matches_suppression)");
1518 }
1519}
1520
1521Char* MC_(get_error_name) ( Error* err )
1522{
1523 switch (VG_(get_error_kind)(err)) {
1524 case Err_RegParam: return "Param";
1525 case Err_MemParam: return "Param";
1526 case Err_User: return "User";
1527 case Err_FreeMismatch: return "Free";
1528 case Err_IllegalMempool: return "Mempool";
1529 case Err_Free: return "Free";
1530 case Err_Jump: return "Jump";
1531 case Err_CoreMem: return "CoreMem";
1532 case Err_Overlap: return "Overlap";
1533 case Err_Leak: return "Leak";
1534 case Err_Cond: return "Cond";
1535 case Err_Addr: {
1536 MC_Error* extra = VG_(get_error_extra)(err);
1537 switch ( extra->Err.Addr.szB ) {
1538 case 1: return "Addr1";
1539 case 2: return "Addr2";
1540 case 4: return "Addr4";
1541 case 8: return "Addr8";
1542 case 16: return "Addr16";
1543 default: VG_(tool_panic)("unexpected size for Addr");
1544 }
1545 }
1546 case Err_Value: {
1547 MC_Error* extra = VG_(get_error_extra)(err);
1548 switch ( extra->Err.Value.szB ) {
1549 case 1: return "Value1";
1550 case 2: return "Value2";
1551 case 4: return "Value4";
1552 case 8: return "Value8";
1553 case 16: return "Value16";
1554 default: VG_(tool_panic)("unexpected size for Value");
1555 }
1556 }
1557 default: VG_(tool_panic)("get_error_name: unexpected type");
1558 }
1559}
1560
sewardj588adef2009-08-15 22:41:51 +00001561Bool MC_(get_extra_suppression_info) ( Error* err,
1562 /*OUT*/Char* buf, Int nBuf )
sewardj7ce71662008-05-02 10:33:15 +00001563{
1564 ErrorKind ekind = VG_(get_error_kind )(err);
sewardj588adef2009-08-15 22:41:51 +00001565 tl_assert(buf);
1566 tl_assert(nBuf >= 16); // stay sane
sewardj7ce71662008-05-02 10:33:15 +00001567 if (Err_RegParam == ekind || Err_MemParam == ekind) {
sewardj588adef2009-08-15 22:41:51 +00001568 Char* errstr = VG_(get_error_string)(err);
1569 tl_assert(errstr);
1570 VG_(snprintf)(buf, nBuf-1, "%s", errstr);
1571 return True;
1572 } else {
1573 return False;
sewardj7ce71662008-05-02 10:33:15 +00001574 }
1575}
1576
1577
1578/*--------------------------------------------------------------------*/
1579/*--- end mc_errors.c ---*/
1580/*--------------------------------------------------------------------*/