1 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 11 Copyright (C) 2000-2012 Julian Seward 12 jseward (at) 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" 33 #include "pub_tool_gdbserver.h" 34 #include "pub_tool_poolalloc.h" // For mc_include.h 35 #include "pub_tool_hashtable.h" // For mc_include.h 36 #include "pub_tool_libcbase.h" 37 #include "pub_tool_libcassert.h" 38 #include "pub_tool_libcprint.h" 39 #include "pub_tool_machine.h" 40 #include "pub_tool_mallocfree.h" 41 #include "pub_tool_options.h" 42 #include "pub_tool_replacemalloc.h" 43 #include "pub_tool_tooliface.h" 44 #include "pub_tool_threadstate.h" 45 #include "pub_tool_debuginfo.h" // VG_(get_dataname_and_offset) 46 #include "pub_tool_xarray.h" 47 48 #include "mc_include.h" 49 50 51 /*------------------------------------------------------------*/ 52 /*--- Error types ---*/ 53 /*------------------------------------------------------------*/ 54 55 /* See comment in mc_include.h */ 56 Bool MC_(any_value_errors) = False; 57 58 59 // Different kinds of blocks. 60 typedef 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. */ 71 typedef 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 83 typedef 84 struct _AddrInfo 85 AddrInfo; 86 87 struct _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; 104 PtrdiffT rwoffset; 105 ExeContext* lastchange; 106 } Block; 107 108 // In a global .data symbol. This holds the first 127 chars of 109 // the variable's name (zero terminated), plus a (memory) offset. 110 struct { 111 Char name[128]; 112 PtrdiffT offset; 113 } DataSym; 114 115 // Is described by Dwarf debug info. XArray*s of HChar. 116 struct { 117 XArray* /* of HChar */ descr1; 118 XArray* /* of HChar */ descr2; 119 } 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. */ 137 typedef 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 156 typedef struct _MC_Error MC_Error; 157 158 struct _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; 247 LossRecord* lr; 248 } 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 263 /* 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 */ 267 void 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 */ 273 static 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 } 281 static void emit ( HChar* format, ... ) PRINTF_CHECK(1, 2); 282 static void emit ( HChar* format, ... ) 283 { 284 va_list vargs; 285 va_start(vargs, format); 286 emit_WRK(format, vargs); 287 va_end(vargs); 288 } 289 static 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 298 static 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) { 306 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 ); 309 } else { 310 emit( "%sAddress 0x%llx " 311 "is not stack'd, malloc'd or (recently) free'd%s\n", 312 xpre, (ULong)a, xpost ); 313 } 314 break; 315 316 case Addr_Stack: 317 emit( "%sAddress 0x%llx is on thread %d's stack%s\n", 318 xpre, (ULong)a, ai->Addr.Stack.tid, xpost ); 319 break; 320 321 case Addr_Block: { 322 SizeT block_szB = ai->Addr.Block.block_szB; 323 PtrdiffT rwoffset = ai->Addr.Block.rwoffset; 324 SizeT delta; 325 const Char* relative; 326 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 } 337 emit( 338 "%sAddress 0x%lx is %'lu bytes %s a %s of size %'lu %s%s\n", 339 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", 345 xpost 346 ); 347 VG_(pp_ExeContext)(ai->Addr.Block.lastchange); 348 break; 349 } 350 351 case Addr_DataSym: 352 emiN( "%sAddress 0x%llx is %llu bytes " 353 "inside data symbol \"%pS\"%s\n", 354 xpre, 355 (ULong)a, 356 (ULong)ai->Addr.DataSym.offset, 357 ai->Addr.DataSym.name, 358 xpost ); 359 break; 360 361 case Addr_Variable: 362 /* 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) ); 373 break; 374 375 case Addr_SectKind: 376 emiN( "%sAddress 0x%llx is in the %pS segment of %pS%s\n", 377 xpre, 378 (ULong)a, 379 VG_(pp_SectKind)(ai->Addr.SectKind.kind), 380 ai->Addr.SectKind.objname, 381 xpost ); 382 break; 383 384 default: 385 VG_(tool_panic)("mc_pp_AddrInfo"); 386 } 387 } 388 389 static 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; 395 case Possible: loss = "possibly lost"; break; 396 case Reachable: loss = "still reachable"; break; 397 } 398 return loss; 399 } 400 401 static 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; 407 case Possible: loss = "Leak_PossiblyLost"; break; 408 case Reachable: loss = "Leak_StillReachable"; break; 409 } 410 return loss; 411 } 412 413 static void mc_pp_origin ( ExeContext* ec, UInt okind ) 414 { 415 HChar* src = NULL; 416 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)) { 427 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 ); 433 } 434 } 435 436 char * 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 450 static 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 533 void 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 539 void MC_(pp_Error) ( Error* err ) 540 { 541 const Bool xml = VG_(clo_xml); /* a shorthand */ 542 MC_Error* extra = VG_(get_error_extra)(err); 543 544 switch (VG_(get_error_kind)(err)) { 545 case Err_CoreMem: 546 /* 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 */ 549 // 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" ); 553 emiN( " <what>%pS contains unaddressable byte(s)</what>\n", 554 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 } 561 break; 562 563 case Err_Value: 564 MC_(any_value_errors) = True; 565 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 ); 573 } else { 574 /* 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 ); 582 } 583 break; 584 585 case Err_Cond: 586 MC_(any_value_errors) = True; 587 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 ); 595 } else { 596 /* 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 ); 604 } 605 break; 606 607 case Err_RegParam: 608 MC_(any_value_errors) = True; 609 if (xml) { 610 emit( " <kind>SyscallParam</kind>\n" ); 611 emiN( " <what>Syscall param %pS contains " 612 "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 } 626 break; 627 628 case Err_MemParam: 629 if (!extra->Err.MemParam.isAddrErr) 630 MC_(any_value_errors) = True; 631 if (xml) { 632 emit( " <kind>SyscallParam</kind>\n" ); 633 emiN( " <what>Syscall param %pS points to %s byte(s)</what>\n", 634 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 } 657 break; 658 659 case Err_User: 660 if (!extra->Err.User.isAddrErr) 661 MC_(any_value_errors) = True; 662 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 } 685 break; 686 687 case Err_Free: 688 if (xml) { 689 emit( " <kind>InvalidFree</kind>\n" ); 690 emit( " <what>Invalid free() / delete / delete[]" 691 " / realloc()</what>\n" ); 692 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 { 696 emit( "Invalid free() / delete / delete[] / realloc()\n" ); 697 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 698 mc_pp_AddrInfo( VG_(get_error_address)(err), 699 &extra->Err.Free.ai, False ); 700 } 701 break; 702 703 case Err_FreeMismatch: 704 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 } 716 break; 717 718 case Err_Addr: 719 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 ); 729 } else { 730 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 ); 738 } 739 break; 740 741 case Err_Jump: 742 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 } 755 break; 756 757 case Err_Overlap: 758 if (xml) { 759 emit( " <kind>Overlap</kind>\n" ); 760 if (extra->Err.Overlap.szB == 0) { 761 emiN( " <what>Source and destination overlap " 762 "in %pS(%#lx, %#lx)\n</what>\n", 763 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) { 775 emiN( "Source and destination overlap in %pS(%#lx, %#lx)\n", 776 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 } 786 break; 787 788 case Err_IllegalMempool: 789 // 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 } 803 break; 804 805 case Err_Leak: { 806 UInt n_this_record = extra->Err.Leak.n_this_record; 807 UInt n_total_records = extra->Err.Leak.n_total_records; 808 LossRecord* lr = extra->Err.Leak.lr; 809 pp_LossRecord (n_this_record, n_total_records, lr, xml); 810 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. */ 830 static Bool is_just_below_ESP( Addr esp, Addr aa ) 831 { 832 esp -= VG_STACK_REDZONE_SZB; 833 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 841 void 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 850 if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB)) 851 return; 852 853 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 867 void 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 879 void 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 892 /* This is for memory errors in signal-related memory. */ 893 void MC_(record_core_mem_error) ( ThreadId tid, Char* msg ) 894 { 895 VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL ); 896 } 897 898 void 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 909 void 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 927 void 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 935 void 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 943 void 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 958 void 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 966 void 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 978 Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record, 979 UInt n_total_records, LossRecord* lr, 980 Bool print_record, Bool count_error ) 981 { 982 MC_Error extra; 983 extra.Err.Leak.n_this_record = n_this_record; 984 extra.Err.Leak.n_total_records = n_total_records; 985 extra.Err.Leak.lr = lr; 986 return 987 VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra, 988 lr->key.allocated_at, print_record, 989 /*allow_GDB_attach*/False, count_error ); 990 } 991 992 void 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. */ 1018 Bool 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 1080 /* Functions used when searching MC_Chunk lists */ 1081 static 1082 Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a) 1083 { 1084 return VG_(addr_is_in_block)( a, mc->data, mc->szB, 1085 MC_(Malloc_Redzone_SzB) ); 1086 } 1087 static 1088 Bool 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 } 1093 1094 // Forward declarations 1095 static Bool client_block_maybe_describe( Addr a, AddrInfo* ai ); 1096 static Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai ); 1097 1098 1099 /* Describe an address as best you can, for error messages, 1100 putting the result in ai. */ 1101 static 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 1110 /* -- Perhaps it's a user-named block? -- */ 1111 if (client_block_maybe_describe( a, ai )) { 1112 return; 1113 } 1114 /* -- Perhaps it's in mempool block? -- */ 1115 if (mempool_block_maybe_describe( a, ai )) { 1116 return; 1117 } 1118 /* 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 } 1142 /* -- Search for a recently freed block which might bracket it. -- */ 1143 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; 1152 } 1153 /* -- 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) { 1183 ai->tag = Addr_Variable; 1184 return; 1185 } 1186 /* -- Have a look at the low level data symbols - perhaps it's in 1187 there. -- */ 1188 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 } 1199 /* -- Perhaps it's on a thread's stack? -- */ 1200 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 } 1208 /* -- last ditch attempt at classification -- */ 1209 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, "???" ); 1213 sect = VG_(DebugInfo_sect_kind)( &ai->Addr.SectKind.objname[0], 1214 sizeof(ai->Addr.SectKind.objname)-1, a); 1215 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 } 1222 /* -- Clueless ... -- */ 1223 ai->tag = Addr_Unknown; 1224 return; 1225 } 1226 1227 void 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 1236 /* Fill in *origin_ec as specified by otag, or NULL it out if otag 1237 does not refer to a known origin. */ 1238 static 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). */ 1249 UInt 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 1328 1329 static Bool client_block_maybe_describe( Addr a, 1330 /*OUT*/AddrInfo* ai ) 1331 { 1332 UWord i; 1333 CGenBlock* cgbs = NULL; 1334 UWord cgb_used = 0; 1335 1336 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)) { 1346 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; 1350 ai->Addr.Block.rwoffset = (Word)(a) - (Word)(cgbs[i].start); 1351 ai->Addr.Block.lastchange = cgbs[i].where; 1352 return True; 1353 } 1354 } 1355 return False; 1356 } 1357 1358 1359 static 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 1387 /*------------------------------------------------------------*/ 1388 /*--- Suppressions ---*/ 1389 /*------------------------------------------------------------*/ 1390 1391 typedef 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 1414 Bool 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 1445 Bool MC_(read_extra_suppression_info) ( Int fd, Char** bufpp, 1446 SizeT* nBufp, Supp *su ) 1447 { 1448 Bool eof; 1449 1450 if (VG_(get_supp_kind)(su) == ParamSupp) { 1451 eof = VG_(get_line) ( fd, bufpp, nBufp, NULL ); 1452 if (eof) return False; 1453 VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp)); 1454 } 1455 return True; 1456 } 1457 1458 Bool 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 1521 Char* 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 1561 Bool MC_(get_extra_suppression_info) ( Error* err, 1562 /*OUT*/Char* buf, Int nBuf ) 1563 { 1564 ErrorKind ekind = VG_(get_error_kind )(err); 1565 tl_assert(buf); 1566 tl_assert(nBuf >= 16); // stay sane 1567 if (Err_RegParam == ekind || Err_MemParam == ekind) { 1568 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; 1574 } 1575 } 1576 1577 1578 /*--------------------------------------------------------------------*/ 1579 /*--- end mc_errors.c ---*/ 1580 /*--------------------------------------------------------------------*/ 1581