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-2017 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 #include "pub_tool_aspacemgr.h" 48 #include "pub_tool_addrinfo.h" 49 50 #include "mc_include.h" 51 52 53 /*------------------------------------------------------------*/ 54 /*--- Error types ---*/ 55 /*------------------------------------------------------------*/ 56 57 /* See comment in mc_include.h */ 58 Bool MC_(any_value_errors) = False; 59 60 61 /* ------------------ Errors ----------------------- */ 62 63 /* What kind of error it is. */ 64 typedef 65 enum { 66 Err_Value, 67 Err_Cond, 68 Err_CoreMem, 69 Err_Addr, 70 Err_Jump, 71 Err_RegParam, 72 Err_MemParam, 73 Err_User, 74 Err_Free, 75 Err_FreeMismatch, 76 Err_Overlap, 77 Err_Leak, 78 Err_IllegalMempool, 79 Err_FishyValue, 80 } 81 MC_ErrorTag; 82 83 84 typedef struct _MC_Error MC_Error; 85 86 struct _MC_Error { 87 // Nb: we don't need the tag here, as it's stored in the Error type! Yuk. 88 //MC_ErrorTag tag; 89 90 union { 91 // Use of an undefined value: 92 // - as a pointer in a load or store 93 // - as a jump target 94 struct { 95 SizeT szB; // size of value in bytes 96 // Origin info 97 UInt otag; // origin tag 98 ExeContext* origin_ec; // filled in later 99 } Value; 100 101 // Use of an undefined value in a conditional branch or move. 102 struct { 103 // Origin info 104 UInt otag; // origin tag 105 ExeContext* origin_ec; // filled in later 106 } Cond; 107 108 // Addressability error in core (signal-handling) operation. 109 // It would be good to get rid of this error kind, merge it with 110 // another one somehow. 111 struct { 112 } CoreMem; 113 114 // Use of an unaddressable memory location in a load or store. 115 struct { 116 Bool isWrite; // read or write? 117 SizeT szB; // not used for exec (jump) errors 118 Bool maybe_gcc; // True if just below %esp -- could be a gcc bug 119 AddrInfo ai; 120 } Addr; 121 122 // Jump to an unaddressable memory location. 123 struct { 124 AddrInfo ai; 125 } Jump; 126 127 // System call register input contains undefined bytes. 128 struct { 129 // Origin info 130 UInt otag; // origin tag 131 ExeContext* origin_ec; // filled in later 132 } RegParam; 133 134 // System call memory input contains undefined/unaddressable bytes 135 struct { 136 Bool isAddrErr; // Addressability or definedness error? 137 AddrInfo ai; 138 // Origin info 139 UInt otag; // origin tag 140 ExeContext* origin_ec; // filled in later 141 } MemParam; 142 143 // Problem found from a client request like CHECK_MEM_IS_ADDRESSABLE. 144 struct { 145 Bool isAddrErr; // Addressability or definedness error? 146 AddrInfo ai; 147 // Origin info 148 UInt otag; // origin tag 149 ExeContext* origin_ec; // filled in later 150 } User; 151 152 // Program tried to free() something that's not a heap block (this 153 // covers double-frees). */ 154 struct { 155 AddrInfo ai; 156 } Free; 157 158 // Program allocates heap block with one function 159 // (malloc/new/new[]/custom) and deallocates with not the matching one. 160 struct { 161 AddrInfo ai; 162 } FreeMismatch; 163 164 // Call to strcpy, memcpy, etc, with overlapping blocks. 165 struct { 166 Addr src; // Source block 167 Addr dst; // Destination block 168 SizeT szB; // Size in bytes; 0 if unused. 169 } Overlap; 170 171 // A memory leak. 172 struct { 173 UInt n_this_record; 174 UInt n_total_records; 175 LossRecord* lr; 176 } Leak; 177 178 // A memory pool error. 179 struct { 180 AddrInfo ai; 181 } IllegalMempool; 182 183 // A fishy function argument value 184 // An argument value is considered fishy if the corresponding 185 // parameter has SizeT type and the value when interpreted as a 186 // signed number is negative. 187 struct { 188 const HChar *function_name; 189 const HChar *argument_name; 190 SizeT value; 191 } FishyValue; 192 } Err; 193 }; 194 195 196 /*------------------------------------------------------------*/ 197 /*--- Printing errors ---*/ 198 /*------------------------------------------------------------*/ 199 200 /* This is the "this error is due to be printed shortly; so have a 201 look at it any print any preamble you want" function. Which, in 202 Memcheck, we don't use. Hence a no-op. 203 */ 204 void MC_(before_pp_Error) ( const Error* err ) { 205 } 206 207 /* Do a printf-style operation on either the XML or normal output 208 channel, depending on the setting of VG_(clo_xml). 209 */ 210 static void emit_WRK ( const HChar* format, va_list vargs ) 211 { 212 if (VG_(clo_xml)) { 213 VG_(vprintf_xml)(format, vargs); 214 } else { 215 VG_(vmessage)(Vg_UserMsg, format, vargs); 216 } 217 } 218 static void emit ( const HChar* format, ... ) PRINTF_CHECK(1, 2); 219 static void emit ( const HChar* format, ... ) 220 { 221 va_list vargs; 222 va_start(vargs, format); 223 emit_WRK(format, vargs); 224 va_end(vargs); 225 } 226 227 228 static const HChar* str_leak_lossmode ( Reachedness lossmode ) 229 { 230 const HChar *loss = "?"; 231 switch (lossmode) { 232 case Unreached: loss = "definitely lost"; break; 233 case IndirectLeak: loss = "indirectly lost"; break; 234 case Possible: loss = "possibly lost"; break; 235 case Reachable: loss = "still reachable"; break; 236 } 237 return loss; 238 } 239 240 static const HChar* xml_leak_kind ( Reachedness lossmode ) 241 { 242 const HChar *loss = "?"; 243 switch (lossmode) { 244 case Unreached: loss = "Leak_DefinitelyLost"; break; 245 case IndirectLeak: loss = "Leak_IndirectlyLost"; break; 246 case Possible: loss = "Leak_PossiblyLost"; break; 247 case Reachable: loss = "Leak_StillReachable"; break; 248 } 249 return loss; 250 } 251 252 const HChar* MC_(parse_leak_kinds_tokens) = 253 "reachable,possible,indirect,definite"; 254 255 UInt MC_(all_Reachedness)(void) 256 { 257 static UInt all; 258 259 if (all == 0) { 260 // Compute a set with all values by doing a parsing of the "all" keyword. 261 Bool parseok = VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens), 262 True,/*allow_all*/ 263 "all", 264 &all); 265 tl_assert (parseok && all); 266 } 267 268 return all; 269 } 270 271 static const HChar* pp_Reachedness_for_leak_kinds(Reachedness r) 272 { 273 switch(r) { 274 case Reachable: return "reachable"; 275 case Possible: return "possible"; 276 case IndirectLeak: return "indirect"; 277 case Unreached: return "definite"; 278 default: tl_assert(0); 279 } 280 } 281 282 static void mc_pp_origin ( ExeContext* ec, UInt okind ) 283 { 284 const HChar* src = NULL; 285 tl_assert(ec); 286 287 switch (okind) { 288 case MC_OKIND_STACK: src = " by a stack allocation"; break; 289 case MC_OKIND_HEAP: src = " by a heap allocation"; break; 290 case MC_OKIND_USER: src = " by a client request"; break; 291 case MC_OKIND_UNKNOWN: src = ""; break; 292 } 293 tl_assert(src); /* guards against invalid 'okind' */ 294 295 if (VG_(clo_xml)) { 296 emit( " <auxwhat>Uninitialised value was created%s</auxwhat>\n", 297 src); 298 VG_(pp_ExeContext)( ec ); 299 } else { 300 emit( " Uninitialised value was created%s\n", src); 301 VG_(pp_ExeContext)( ec ); 302 } 303 } 304 305 HChar * MC_(snprintf_delta) (HChar * buf, Int size, 306 SizeT current_val, SizeT old_val, 307 LeakCheckDeltaMode delta_mode) 308 { 309 // Make sure the buffer size is large enough. With old_val == 0 and 310 // current_val == ULLONG_MAX the delta including inserted commas is: 311 // 18,446,744,073,709,551,615 312 // whose length is 26. Therefore: 313 tl_assert(size >= 26 + 4 + 1); 314 315 if (delta_mode == LCD_Any) 316 buf[0] = '\0'; 317 else if (current_val >= old_val) 318 VG_(snprintf) (buf, size, " (+%'lu)", current_val - old_val); 319 else 320 VG_(snprintf) (buf, size, " (-%'lu)", old_val - current_val); 321 322 return buf; 323 } 324 325 static void pp_LossRecord(UInt n_this_record, UInt n_total_records, 326 LossRecord* lr, Bool xml) 327 { 328 // char arrays to produce the indication of increase/decrease in case 329 // of delta_mode != LCD_Any 330 HChar d_bytes[31]; 331 HChar d_direct_bytes[31]; 332 HChar d_indirect_bytes[31]; 333 HChar d_num_blocks[31]; 334 335 MC_(snprintf_delta) (d_bytes, sizeof(d_bytes), 336 lr->szB + lr->indirect_szB, 337 lr->old_szB + lr->old_indirect_szB, 338 MC_(detect_memory_leaks_last_delta_mode)); 339 MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes), 340 lr->szB, 341 lr->old_szB, 342 MC_(detect_memory_leaks_last_delta_mode)); 343 MC_(snprintf_delta) (d_indirect_bytes, sizeof(d_indirect_bytes), 344 lr->indirect_szB, 345 lr->old_indirect_szB, 346 MC_(detect_memory_leaks_last_delta_mode)); 347 MC_(snprintf_delta) (d_num_blocks, sizeof(d_num_blocks), 348 (SizeT) lr->num_blocks, 349 (SizeT) lr->old_num_blocks, 350 MC_(detect_memory_leaks_last_delta_mode)); 351 352 if (xml) { 353 emit(" <kind>%s</kind>\n", xml_leak_kind(lr->key.state)); 354 if (lr->indirect_szB > 0) { 355 emit( " <xwhat>\n" ); 356 emit( " <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes " 357 "in %'u%s blocks" 358 " are %s in loss record %'u of %'u</text>\n", 359 lr->szB + lr->indirect_szB, d_bytes, 360 lr->szB, d_direct_bytes, 361 lr->indirect_szB, d_indirect_bytes, 362 lr->num_blocks, d_num_blocks, 363 str_leak_lossmode(lr->key.state), 364 n_this_record, n_total_records ); 365 // Nb: don't put commas in these XML numbers 366 emit( " <leakedbytes>%lu</leakedbytes>\n", 367 lr->szB + lr->indirect_szB ); 368 emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks ); 369 emit( " </xwhat>\n" ); 370 } else { 371 emit( " <xwhat>\n" ); 372 emit( " <text>%'lu%s bytes in %'u%s blocks" 373 " are %s in loss record %'u of %'u</text>\n", 374 lr->szB, d_direct_bytes, 375 lr->num_blocks, d_num_blocks, 376 str_leak_lossmode(lr->key.state), 377 n_this_record, n_total_records ); 378 emit( " <leakedbytes>%lu</leakedbytes>\n", lr->szB); 379 emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks); 380 emit( " </xwhat>\n" ); 381 } 382 VG_(pp_ExeContext)(lr->key.allocated_at); 383 } else { /* ! if (xml) */ 384 if (lr->indirect_szB > 0) { 385 emit( 386 "%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks" 387 " are %s in loss record %'u of %'u\n", 388 lr->szB + lr->indirect_szB, d_bytes, 389 lr->szB, d_direct_bytes, 390 lr->indirect_szB, d_indirect_bytes, 391 lr->num_blocks, d_num_blocks, 392 str_leak_lossmode(lr->key.state), 393 n_this_record, n_total_records 394 ); 395 } else { 396 emit( 397 "%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n", 398 lr->szB, d_direct_bytes, 399 lr->num_blocks, d_num_blocks, 400 str_leak_lossmode(lr->key.state), 401 n_this_record, n_total_records 402 ); 403 } 404 VG_(pp_ExeContext)(lr->key.allocated_at); 405 } /* if (xml) */ 406 } 407 408 void MC_(pp_LossRecord)(UInt n_this_record, UInt n_total_records, 409 LossRecord* l) 410 { 411 pp_LossRecord (n_this_record, n_total_records, l, /* xml */ False); 412 } 413 414 void MC_(pp_Error) ( const Error* err ) 415 { 416 const Bool xml = VG_(clo_xml); /* a shorthand */ 417 MC_Error* extra = VG_(get_error_extra)(err); 418 419 switch (VG_(get_error_kind)(err)) { 420 case Err_CoreMem: 421 /* What the hell *is* a CoreMemError? jrs 2005-May-18 */ 422 /* As of 2006-Dec-14, it's caused by unaddressable bytes in a 423 signal handler frame. --njn */ 424 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK 425 // the following code is untested. Bad. 426 if (xml) { 427 emit( " <kind>CoreMemError</kind>\n" ); 428 emit( " <what>%pS contains unaddressable byte(s)</what>\n", 429 VG_(get_error_string)(err)); 430 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 431 } else { 432 emit( "%s contains unaddressable byte(s)\n", 433 VG_(get_error_string)(err)); 434 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 435 } 436 break; 437 438 case Err_Value: 439 MC_(any_value_errors) = True; 440 if (xml) { 441 emit( " <kind>UninitValue</kind>\n" ); 442 emit( " <what>Use of uninitialised value of size %lu</what>\n", 443 extra->Err.Value.szB ); 444 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 445 if (extra->Err.Value.origin_ec) 446 mc_pp_origin( extra->Err.Value.origin_ec, 447 extra->Err.Value.otag & 3 ); 448 } else { 449 /* Could also show extra->Err.Cond.otag if debugging origin 450 tracking */ 451 emit( "Use of uninitialised value of size %lu\n", 452 extra->Err.Value.szB ); 453 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 454 if (extra->Err.Value.origin_ec) 455 mc_pp_origin( extra->Err.Value.origin_ec, 456 extra->Err.Value.otag & 3 ); 457 } 458 break; 459 460 case Err_Cond: 461 MC_(any_value_errors) = True; 462 if (xml) { 463 emit( " <kind>UninitCondition</kind>\n" ); 464 emit( " <what>Conditional jump or move depends" 465 " on uninitialised value(s)</what>\n" ); 466 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 467 if (extra->Err.Cond.origin_ec) 468 mc_pp_origin( extra->Err.Cond.origin_ec, 469 extra->Err.Cond.otag & 3 ); 470 } else { 471 /* Could also show extra->Err.Cond.otag if debugging origin 472 tracking */ 473 emit( "Conditional jump or move depends" 474 " on uninitialised value(s)\n" ); 475 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 476 if (extra->Err.Cond.origin_ec) 477 mc_pp_origin( extra->Err.Cond.origin_ec, 478 extra->Err.Cond.otag & 3 ); 479 } 480 break; 481 482 case Err_RegParam: 483 MC_(any_value_errors) = True; 484 if (xml) { 485 emit( " <kind>SyscallParam</kind>\n" ); 486 emit( " <what>Syscall param %pS contains " 487 "uninitialised byte(s)</what>\n", 488 VG_(get_error_string)(err) ); 489 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 490 if (extra->Err.RegParam.origin_ec) 491 mc_pp_origin( extra->Err.RegParam.origin_ec, 492 extra->Err.RegParam.otag & 3 ); 493 } else { 494 emit( "Syscall param %s contains uninitialised byte(s)\n", 495 VG_(get_error_string)(err) ); 496 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 497 if (extra->Err.RegParam.origin_ec) 498 mc_pp_origin( extra->Err.RegParam.origin_ec, 499 extra->Err.RegParam.otag & 3 ); 500 } 501 break; 502 503 case Err_MemParam: 504 if (!extra->Err.MemParam.isAddrErr) 505 MC_(any_value_errors) = True; 506 if (xml) { 507 emit( " <kind>SyscallParam</kind>\n" ); 508 emit( " <what>Syscall param %pS points to %s byte(s)</what>\n", 509 VG_(get_error_string)(err), 510 extra->Err.MemParam.isAddrErr 511 ? "unaddressable" : "uninitialised" ); 512 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 513 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), 514 &extra->Err.MemParam.ai, False); 515 if (extra->Err.MemParam.origin_ec 516 && !extra->Err.MemParam.isAddrErr) 517 mc_pp_origin( extra->Err.MemParam.origin_ec, 518 extra->Err.MemParam.otag & 3 ); 519 } else { 520 emit( "Syscall param %s points to %s byte(s)\n", 521 VG_(get_error_string)(err), 522 extra->Err.MemParam.isAddrErr 523 ? "unaddressable" : "uninitialised" ); 524 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 525 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), 526 &extra->Err.MemParam.ai, False); 527 if (extra->Err.MemParam.origin_ec 528 && !extra->Err.MemParam.isAddrErr) 529 mc_pp_origin( extra->Err.MemParam.origin_ec, 530 extra->Err.MemParam.otag & 3 ); 531 } 532 break; 533 534 case Err_User: 535 if (!extra->Err.User.isAddrErr) 536 MC_(any_value_errors) = True; 537 if (xml) { 538 emit( " <kind>ClientCheck</kind>\n" ); 539 emit( " <what>%s byte(s) found " 540 "during client check request</what>\n", 541 extra->Err.User.isAddrErr 542 ? "Unaddressable" : "Uninitialised" ); 543 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 544 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai, 545 False); 546 if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr) 547 mc_pp_origin( extra->Err.User.origin_ec, 548 extra->Err.User.otag & 3 ); 549 } else { 550 emit( "%s byte(s) found during client check request\n", 551 extra->Err.User.isAddrErr 552 ? "Unaddressable" : "Uninitialised" ); 553 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 554 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), &extra->Err.User.ai, 555 False); 556 if (extra->Err.User.origin_ec && !extra->Err.User.isAddrErr) 557 mc_pp_origin( extra->Err.User.origin_ec, 558 extra->Err.User.otag & 3 ); 559 } 560 break; 561 562 case Err_Free: 563 if (xml) { 564 emit( " <kind>InvalidFree</kind>\n" ); 565 emit( " <what>Invalid free() / delete / delete[]" 566 " / realloc()</what>\n" ); 567 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 568 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 569 &extra->Err.Free.ai, False ); 570 } else { 571 emit( "Invalid free() / delete / delete[] / realloc()\n" ); 572 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 573 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 574 &extra->Err.Free.ai, False ); 575 } 576 break; 577 578 case Err_FreeMismatch: 579 if (xml) { 580 emit( " <kind>MismatchedFree</kind>\n" ); 581 emit( " <what>Mismatched free() / delete / delete []</what>\n" ); 582 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 583 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), 584 &extra->Err.FreeMismatch.ai, False); 585 } else { 586 emit( "Mismatched free() / delete / delete []\n" ); 587 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 588 VG_(pp_addrinfo_mc)(VG_(get_error_address)(err), 589 &extra->Err.FreeMismatch.ai, False); 590 } 591 break; 592 593 case Err_Addr: 594 if (xml) { 595 emit( " <kind>Invalid%s</kind>\n", 596 extra->Err.Addr.isWrite ? "Write" : "Read" ); 597 emit( " <what>Invalid %s of size %lu</what>\n", 598 extra->Err.Addr.isWrite ? "write" : "read", 599 extra->Err.Addr.szB ); 600 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 601 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 602 &extra->Err.Addr.ai, 603 extra->Err.Addr.maybe_gcc ); 604 } else { 605 emit( "Invalid %s of size %lu\n", 606 extra->Err.Addr.isWrite ? "write" : "read", 607 extra->Err.Addr.szB ); 608 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 609 610 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 611 &extra->Err.Addr.ai, 612 extra->Err.Addr.maybe_gcc ); 613 } 614 break; 615 616 case Err_Jump: 617 if (xml) { 618 emit( " <kind>InvalidJump</kind>\n" ); 619 emit( " <what>Jump to the invalid address stated " 620 "on the next line</what>\n" ); 621 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 622 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai, 623 False ); 624 } else { 625 emit( "Jump to the invalid address stated on the next line\n" ); 626 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 627 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), &extra->Err.Jump.ai, 628 False ); 629 } 630 break; 631 632 case Err_Overlap: 633 if (xml) { 634 emit( " <kind>Overlap</kind>\n" ); 635 if (extra->Err.Overlap.szB == 0) { 636 emit( " <what>Source and destination overlap " 637 "in %pS(%#lx, %#lx)\n</what>\n", 638 VG_(get_error_string)(err), 639 extra->Err.Overlap.dst, extra->Err.Overlap.src ); 640 } else { 641 emit( " <what>Source and destination overlap " 642 "in %pS(%#lx, %#lx, %lu)</what>\n", 643 VG_(get_error_string)(err), 644 extra->Err.Overlap.dst, extra->Err.Overlap.src, 645 extra->Err.Overlap.szB ); 646 } 647 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 648 } else { 649 if (extra->Err.Overlap.szB == 0) { 650 emit( "Source and destination overlap in %s(%#lx, %#lx)\n", 651 VG_(get_error_string)(err), 652 extra->Err.Overlap.dst, extra->Err.Overlap.src ); 653 } else { 654 emit( "Source and destination overlap in %s(%#lx, %#lx, %lu)\n", 655 VG_(get_error_string)(err), 656 extra->Err.Overlap.dst, extra->Err.Overlap.src, 657 extra->Err.Overlap.szB ); 658 } 659 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 660 } 661 break; 662 663 case Err_IllegalMempool: 664 // JRS 17 May 09: None of our regtests exercise this; hence AFAIK 665 // the following code is untested. Bad. 666 if (xml) { 667 emit( " <kind>InvalidMemPool</kind>\n" ); 668 emit( " <what>Illegal memory pool address</what>\n" ); 669 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 670 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 671 &extra->Err.IllegalMempool.ai, False ); 672 } else { 673 emit( "Illegal memory pool address\n" ); 674 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 675 VG_(pp_addrinfo_mc)( VG_(get_error_address)(err), 676 &extra->Err.IllegalMempool.ai, False ); 677 } 678 break; 679 680 case Err_Leak: { 681 UInt n_this_record = extra->Err.Leak.n_this_record; 682 UInt n_total_records = extra->Err.Leak.n_total_records; 683 LossRecord* lr = extra->Err.Leak.lr; 684 pp_LossRecord (n_this_record, n_total_records, lr, xml); 685 break; 686 } 687 688 case Err_FishyValue: 689 if (xml) { 690 emit( " <kind>FishyValue</kind>\n" ); 691 emit( " <what>"); 692 emit( "Argument '%s' of function %s has a fishy " 693 "(possibly negative) value: %ld\n", 694 extra->Err.FishyValue.argument_name, 695 extra->Err.FishyValue.function_name, 696 (SSizeT)extra->Err.FishyValue.value); 697 emit( "</what>"); 698 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 699 } else { 700 emit( "Argument '%s' of function %s has a fishy " 701 "(possibly negative) value: %ld\n", 702 extra->Err.FishyValue.argument_name, 703 extra->Err.FishyValue.function_name, 704 (SSizeT)extra->Err.FishyValue.value); 705 VG_(pp_ExeContext)( VG_(get_error_where)(err) ); 706 } 707 break; 708 709 default: 710 VG_(printf)("Error:\n unknown Memcheck error code %d\n", 711 VG_(get_error_kind)(err)); 712 VG_(tool_panic)("unknown error code in mc_pp_Error)"); 713 } 714 } 715 716 /*------------------------------------------------------------*/ 717 /*--- Recording errors ---*/ 718 /*------------------------------------------------------------*/ 719 720 /* These many bytes below %ESP are considered addressible if we're 721 doing the --workaround-gcc296-bugs hack. */ 722 #define VG_GCC296_BUG_STACK_SLOP 1024 723 724 /* Is this address within some small distance below %ESP? Used only 725 for the --workaround-gcc296-bugs kludge. */ 726 static Bool is_just_below_ESP( Addr esp, Addr aa ) 727 { 728 esp -= VG_STACK_REDZONE_SZB; 729 if (esp > aa && (esp - aa) <= VG_GCC296_BUG_STACK_SLOP) 730 return True; 731 else 732 return False; 733 } 734 735 /* --- Called from generated and non-generated code --- */ 736 737 void MC_(record_address_error) ( ThreadId tid, Addr a, Int szB, 738 Bool isWrite ) 739 { 740 MC_Error extra; 741 Bool just_below_esp; 742 743 if (MC_(in_ignored_range)(a)) 744 return; 745 746 if (VG_(is_watched)( (isWrite ? write_watchpoint : read_watchpoint), a, szB)) 747 return; 748 749 Addr current_sp = VG_(get_SP)(tid); 750 just_below_esp = is_just_below_ESP( current_sp, a ); 751 752 /* If this is caused by an access immediately below %ESP, and the 753 user asks nicely, we just ignore it. */ 754 if (MC_(clo_workaround_gcc296_bugs) && just_below_esp) 755 return; 756 757 /* Also, if this is caused by an access in the range of offsets 758 below the stack pointer as described by 759 --ignore-range-below-sp, ignore it. */ 760 if (MC_(in_ignored_range_below_sp)( current_sp, a, szB )) 761 return; 762 763 extra.Err.Addr.isWrite = isWrite; 764 extra.Err.Addr.szB = szB; 765 extra.Err.Addr.maybe_gcc = just_below_esp; 766 extra.Err.Addr.ai.tag = Addr_Undescribed; 767 VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra ); 768 } 769 770 void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag ) 771 { 772 MC_Error extra; 773 tl_assert( MC_(clo_mc_level) >= 2 ); 774 if (otag > 0) 775 tl_assert( MC_(clo_mc_level) == 3 ); 776 extra.Err.Value.szB = szB; 777 extra.Err.Value.otag = otag; 778 extra.Err.Value.origin_ec = NULL; /* Filled in later */ 779 VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra ); 780 } 781 782 void MC_(record_cond_error) ( ThreadId tid, UInt otag ) 783 { 784 MC_Error extra; 785 tl_assert( MC_(clo_mc_level) >= 2 ); 786 if (otag > 0) 787 tl_assert( MC_(clo_mc_level) == 3 ); 788 extra.Err.Cond.otag = otag; 789 extra.Err.Cond.origin_ec = NULL; /* Filled in later */ 790 VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra ); 791 } 792 793 /* --- Called from non-generated code --- */ 794 795 /* This is for memory errors in signal-related memory. */ 796 void MC_(record_core_mem_error) ( ThreadId tid, const HChar* msg ) 797 { 798 VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL ); 799 } 800 801 void MC_(record_regparam_error) ( ThreadId tid, const HChar* msg, UInt otag ) 802 { 803 MC_Error extra; 804 tl_assert(VG_INVALID_THREADID != tid); 805 if (otag > 0) 806 tl_assert( MC_(clo_mc_level) == 3 ); 807 extra.Err.RegParam.otag = otag; 808 extra.Err.RegParam.origin_ec = NULL; /* Filled in later */ 809 VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra ); 810 } 811 812 void MC_(record_memparam_error) ( ThreadId tid, Addr a, 813 Bool isAddrErr, const HChar* msg, UInt otag ) 814 { 815 MC_Error extra; 816 tl_assert(VG_INVALID_THREADID != tid); 817 if (!isAddrErr) 818 tl_assert( MC_(clo_mc_level) >= 2 ); 819 if (otag != 0) { 820 tl_assert( MC_(clo_mc_level) == 3 ); 821 tl_assert( !isAddrErr ); 822 } 823 extra.Err.MemParam.isAddrErr = isAddrErr; 824 extra.Err.MemParam.ai.tag = Addr_Undescribed; 825 extra.Err.MemParam.otag = otag; 826 extra.Err.MemParam.origin_ec = NULL; /* Filled in later */ 827 VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra ); 828 } 829 830 void MC_(record_jump_error) ( ThreadId tid, Addr a ) 831 { 832 MC_Error extra; 833 tl_assert(VG_INVALID_THREADID != tid); 834 extra.Err.Jump.ai.tag = Addr_Undescribed; 835 VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra ); 836 } 837 838 void MC_(record_free_error) ( ThreadId tid, Addr a ) 839 { 840 MC_Error extra; 841 tl_assert(VG_INVALID_THREADID != tid); 842 extra.Err.Free.ai.tag = Addr_Undescribed; 843 VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra ); 844 } 845 846 void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc ) 847 { 848 MC_Error extra; 849 AddrInfo* ai = &extra.Err.FreeMismatch.ai; 850 tl_assert(VG_INVALID_THREADID != tid); 851 ai->tag = Addr_Block; 852 ai->Addr.Block.block_kind = Block_Mallocd; // Nb: Not 'Block_Freed' 853 ai->Addr.Block.block_desc = "block"; 854 ai->Addr.Block.block_szB = mc->szB; 855 ai->Addr.Block.rwoffset = 0; 856 ai->Addr.Block.allocated_at = MC_(allocated_at) (mc); 857 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 858 ai->Addr.Block.freed_at = MC_(freed_at) (mc); 859 VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL, 860 &extra ); 861 } 862 863 void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a ) 864 { 865 MC_Error extra; 866 tl_assert(VG_INVALID_THREADID != tid); 867 extra.Err.IllegalMempool.ai.tag = Addr_Undescribed; 868 VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra ); 869 } 870 871 void MC_(record_overlap_error) ( ThreadId tid, const HChar* function, 872 Addr src, Addr dst, SizeT szB ) 873 { 874 MC_Error extra; 875 tl_assert(VG_INVALID_THREADID != tid); 876 extra.Err.Overlap.src = src; 877 extra.Err.Overlap.dst = dst; 878 extra.Err.Overlap.szB = szB; 879 VG_(maybe_record_error)( 880 tid, Err_Overlap, /*addr*/0, /*s*/function, &extra ); 881 } 882 883 Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record, 884 UInt n_total_records, LossRecord* lr, 885 Bool print_record, Bool count_error ) 886 { 887 MC_Error extra; 888 extra.Err.Leak.n_this_record = n_this_record; 889 extra.Err.Leak.n_total_records = n_total_records; 890 extra.Err.Leak.lr = lr; 891 return 892 VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra, 893 lr->key.allocated_at, print_record, 894 /*allow_GDB_attach*/False, count_error ); 895 } 896 897 Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name, 898 const HChar *argument_name, SizeT value) 899 { 900 MC_Error extra; 901 902 tl_assert(VG_INVALID_THREADID != tid); 903 904 if ((SSizeT)value >= 0) return False; // not a fishy value 905 906 extra.Err.FishyValue.function_name = function_name; 907 extra.Err.FishyValue.argument_name = argument_name; 908 extra.Err.FishyValue.value = value; 909 910 VG_(maybe_record_error)( 911 tid, Err_FishyValue, /*addr*/0, /*s*/NULL, &extra ); 912 913 return True; 914 } 915 916 void MC_(record_user_error) ( ThreadId tid, Addr a, 917 Bool isAddrErr, UInt otag ) 918 { 919 MC_Error extra; 920 if (otag != 0) { 921 tl_assert(!isAddrErr); 922 tl_assert( MC_(clo_mc_level) == 3 ); 923 } 924 if (!isAddrErr) { 925 tl_assert( MC_(clo_mc_level) >= 2 ); 926 } 927 tl_assert(VG_INVALID_THREADID != tid); 928 extra.Err.User.isAddrErr = isAddrErr; 929 extra.Err.User.ai.tag = Addr_Undescribed; 930 extra.Err.User.otag = otag; 931 extra.Err.User.origin_ec = NULL; /* Filled in later */ 932 VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra ); 933 } 934 935 Bool MC_(is_mempool_block)(MC_Chunk* mc_search) 936 { 937 MC_Mempool* mp; 938 939 if (!MC_(mempool_list)) 940 return False; 941 942 // A chunk can only come from a mempool if a custom allocator 943 // is used. No search required for other kinds. 944 if (mc_search->allockind == MC_AllocCustom) { 945 VG_(HT_ResetIter)( MC_(mempool_list) ); 946 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) { 947 MC_Chunk* mc; 948 VG_(HT_ResetIter)(mp->chunks); 949 while ( (mc = VG_(HT_Next)(mp->chunks)) ) { 950 if (mc == mc_search) 951 return True; 952 } 953 } 954 } 955 956 return False; 957 } 958 959 /*------------------------------------------------------------*/ 960 /*--- Other error operations ---*/ 961 /*------------------------------------------------------------*/ 962 963 /* Compare error contexts, to detect duplicates. Note that if they 964 are otherwise the same, the faulting addrs and associated rwoffsets 965 are allowed to be different. */ 966 Bool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 ) 967 { 968 MC_Error* extra1 = VG_(get_error_extra)(e1); 969 MC_Error* extra2 = VG_(get_error_extra)(e2); 970 971 /* Guaranteed by calling function */ 972 tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2)); 973 974 switch (VG_(get_error_kind)(e1)) { 975 case Err_CoreMem: { 976 const HChar *e1s, *e2s; 977 e1s = VG_(get_error_string)(e1); 978 e2s = VG_(get_error_string)(e2); 979 if (e1s == e2s) return True; 980 if (VG_STREQ(e1s, e2s)) return True; 981 return False; 982 } 983 984 case Err_RegParam: 985 return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2)); 986 987 // Perhaps we should also check the addrinfo.akinds for equality. 988 // That would result in more error reports, but only in cases where 989 // a register contains uninitialised bytes and points to memory 990 // containing uninitialised bytes. Currently, the 2nd of those to be 991 // detected won't be reported. That is (nearly?) always the memory 992 // error, which is good. 993 case Err_MemParam: 994 if (!VG_STREQ(VG_(get_error_string)(e1), 995 VG_(get_error_string)(e2))) return False; 996 // fall through 997 case Err_User: 998 return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr 999 ? True : False ); 1000 1001 case Err_Free: 1002 case Err_FreeMismatch: 1003 case Err_Jump: 1004 case Err_IllegalMempool: 1005 case Err_Overlap: 1006 case Err_Cond: 1007 return True; 1008 1009 case Err_FishyValue: 1010 return VG_STREQ(extra1->Err.FishyValue.function_name, 1011 extra2->Err.FishyValue.function_name) && 1012 VG_STREQ(extra1->Err.FishyValue.argument_name, 1013 extra2->Err.FishyValue.argument_name); 1014 1015 case Err_Addr: 1016 return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB 1017 ? True : False ); 1018 1019 case Err_Value: 1020 return ( extra1->Err.Value.szB == extra2->Err.Value.szB 1021 ? True : False ); 1022 1023 case Err_Leak: 1024 VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n" 1025 "since it's handled with VG_(unique_error)()!"); 1026 1027 default: 1028 VG_(printf)("Error:\n unknown error code %d\n", 1029 VG_(get_error_kind)(e1)); 1030 VG_(tool_panic)("unknown error code in mc_eq_Error"); 1031 } 1032 } 1033 1034 /* Functions used when searching MC_Chunk lists */ 1035 static 1036 Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a) 1037 { 1038 return VG_(addr_is_in_block)( a, mc->data, mc->szB, 1039 MC_(Malloc_Redzone_SzB) ); 1040 } 1041 static 1042 Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB) 1043 { 1044 return VG_(addr_is_in_block)( a, mc->data, mc->szB, 1045 rzB ); 1046 } 1047 1048 // Forward declarations 1049 static Bool client_block_maybe_describe( Addr a, AddrInfo* ai ); 1050 static Bool mempool_block_maybe_describe( Addr a, Bool is_metapool, 1051 AddrInfo* ai ); 1052 1053 1054 /* Describe an address as best you can, for error messages, 1055 putting the result in ai. */ 1056 static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai ) 1057 { 1058 MC_Chunk* mc; 1059 1060 tl_assert(Addr_Undescribed == ai->tag); 1061 1062 /* -- Perhaps it's a user-named block? -- */ 1063 if (client_block_maybe_describe( a, ai )) { 1064 return; 1065 } 1066 1067 /* -- Perhaps it's in mempool block (non-meta)? -- */ 1068 if (mempool_block_maybe_describe( a, /*is_metapool*/ False, ai)) { 1069 return; 1070 } 1071 1072 /* Blocks allocated by memcheck malloc functions are either 1073 on the recently freed list or on the malloc-ed list. 1074 Custom blocks can be on both : a recently freed block might 1075 have been just re-allocated. 1076 So, first search the malloc-ed block, as the most recent 1077 block is the probable cause of error. 1078 We however detect and report that this is a recently re-allocated 1079 block. */ 1080 /* -- Search for a currently malloc'd block which might bracket it. -- */ 1081 VG_(HT_ResetIter)(MC_(malloc_list)); 1082 while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) { 1083 if (!MC_(is_mempool_block)(mc) && 1084 addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) { 1085 ai->tag = Addr_Block; 1086 ai->Addr.Block.block_kind = Block_Mallocd; 1087 if (MC_(get_freed_block_bracketting)( a )) 1088 ai->Addr.Block.block_desc = "recently re-allocated block"; 1089 else 1090 ai->Addr.Block.block_desc = "block"; 1091 ai->Addr.Block.block_szB = mc->szB; 1092 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1093 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc); 1094 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 1095 ai->Addr.Block.freed_at = MC_(freed_at)(mc); 1096 return; 1097 } 1098 } 1099 /* -- Search for a recently freed block which might bracket it. -- */ 1100 mc = MC_(get_freed_block_bracketting)( a ); 1101 if (mc) { 1102 ai->tag = Addr_Block; 1103 ai->Addr.Block.block_kind = Block_Freed; 1104 ai->Addr.Block.block_desc = "block"; 1105 ai->Addr.Block.block_szB = mc->szB; 1106 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1107 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc); 1108 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 1109 ai->Addr.Block.freed_at = MC_(freed_at)(mc); 1110 return; 1111 } 1112 1113 /* -- Perhaps it's in a meta mempool block? -- */ 1114 /* This test is done last, because metapool blocks overlap with blocks 1115 handed out to the application. That makes every heap address part of 1116 a metapool block, so the interesting cases are handled first. 1117 This final search is a last-ditch attempt. When found, it is probably 1118 an error in the custom allocator itself. */ 1119 if (mempool_block_maybe_describe( a, /*is_metapool*/ True, ai )) { 1120 return; 1121 } 1122 1123 /* No block found. Search a non-heap block description. */ 1124 VG_(describe_addr) (a, ai); 1125 } 1126 1127 void MC_(pp_describe_addr) ( Addr a ) 1128 { 1129 AddrInfo ai; 1130 1131 ai.tag = Addr_Undescribed; 1132 describe_addr (a, &ai); 1133 VG_(pp_addrinfo_mc) (a, &ai, /* maybe_gcc */ False); 1134 VG_(clear_addrinfo) (&ai); 1135 } 1136 1137 /* Fill in *origin_ec as specified by otag, or NULL it out if otag 1138 does not refer to a known origin. */ 1139 static void update_origin ( /*OUT*/ExeContext** origin_ec, 1140 UInt otag ) 1141 { 1142 UInt ecu = otag & ~3; 1143 *origin_ec = NULL; 1144 if (VG_(is_plausible_ECU)(ecu)) { 1145 *origin_ec = VG_(get_ExeContext_from_ECU)( ecu ); 1146 } 1147 } 1148 1149 /* Updates the copy with address info if necessary (but not for all errors). */ 1150 UInt MC_(update_Error_extra)( const Error* err ) 1151 { 1152 MC_Error* extra = VG_(get_error_extra)(err); 1153 1154 switch (VG_(get_error_kind)(err)) { 1155 // These ones don't have addresses associated with them, and so don't 1156 // need any updating. 1157 case Err_CoreMem: 1158 //case Err_Value: 1159 //case Err_Cond: 1160 case Err_Overlap: 1161 case Err_FishyValue: 1162 // For Err_Leaks the returned size does not matter -- they are always 1163 // shown with VG_(unique_error)() so they 'extra' not copied. But 1164 // we make it consistent with the others. 1165 case Err_Leak: 1166 return sizeof(MC_Error); 1167 1168 // For value errors, get the ExeContext corresponding to the 1169 // origin tag. Note that it is a kludge to assume that 1170 // a length-1 trace indicates a stack origin. FIXME. 1171 case Err_Value: 1172 update_origin( &extra->Err.Value.origin_ec, 1173 extra->Err.Value.otag ); 1174 return sizeof(MC_Error); 1175 case Err_Cond: 1176 update_origin( &extra->Err.Cond.origin_ec, 1177 extra->Err.Cond.otag ); 1178 return sizeof(MC_Error); 1179 case Err_RegParam: 1180 update_origin( &extra->Err.RegParam.origin_ec, 1181 extra->Err.RegParam.otag ); 1182 return sizeof(MC_Error); 1183 1184 // These ones always involve a memory address. 1185 case Err_Addr: 1186 describe_addr ( VG_(get_error_address)(err), 1187 &extra->Err.Addr.ai ); 1188 return sizeof(MC_Error); 1189 case Err_MemParam: 1190 describe_addr ( VG_(get_error_address)(err), 1191 &extra->Err.MemParam.ai ); 1192 update_origin( &extra->Err.MemParam.origin_ec, 1193 extra->Err.MemParam.otag ); 1194 return sizeof(MC_Error); 1195 case Err_Jump: 1196 describe_addr ( VG_(get_error_address)(err), 1197 &extra->Err.Jump.ai ); 1198 return sizeof(MC_Error); 1199 case Err_User: 1200 describe_addr ( VG_(get_error_address)(err), 1201 &extra->Err.User.ai ); 1202 update_origin( &extra->Err.User.origin_ec, 1203 extra->Err.User.otag ); 1204 return sizeof(MC_Error); 1205 case Err_Free: 1206 describe_addr ( VG_(get_error_address)(err), 1207 &extra->Err.Free.ai ); 1208 return sizeof(MC_Error); 1209 case Err_IllegalMempool: 1210 describe_addr ( VG_(get_error_address)(err), 1211 &extra->Err.IllegalMempool.ai ); 1212 return sizeof(MC_Error); 1213 1214 // Err_FreeMismatches have already had their address described; this is 1215 // possible because we have the MC_Chunk on hand when the error is 1216 // detected. However, the address may be part of a user block, and if so 1217 // we override the pre-determined description with a user block one. 1218 case Err_FreeMismatch: { 1219 tl_assert(extra && Block_Mallocd == 1220 extra->Err.FreeMismatch.ai.Addr.Block.block_kind); 1221 (void)client_block_maybe_describe( VG_(get_error_address)(err), 1222 &extra->Err.FreeMismatch.ai ); 1223 return sizeof(MC_Error); 1224 } 1225 1226 default: VG_(tool_panic)("mc_update_extra: bad errkind"); 1227 } 1228 } 1229 1230 1231 static Bool client_block_maybe_describe( Addr a, 1232 /*OUT*/AddrInfo* ai ) 1233 { 1234 UWord i; 1235 CGenBlock* cgbs = NULL; 1236 UWord cgb_used = 0; 1237 1238 MC_(get_ClientBlock_array)( &cgbs, &cgb_used ); 1239 if (cgbs == NULL) 1240 tl_assert(cgb_used == 0); 1241 1242 /* Perhaps it's a general block ? */ 1243 for (i = 0; i < cgb_used; i++) { 1244 if (cgbs[i].start == 0 && cgbs[i].size == 0) 1245 continue; 1246 // Use zero as the redzone for client blocks. 1247 if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) { 1248 ai->tag = Addr_Block; 1249 ai->Addr.Block.block_kind = Block_UserG; 1250 ai->Addr.Block.block_desc = cgbs[i].desc; 1251 ai->Addr.Block.block_szB = cgbs[i].size; 1252 ai->Addr.Block.rwoffset = (Word)(a) - (Word)(cgbs[i].start); 1253 ai->Addr.Block.allocated_at = cgbs[i].where; 1254 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 1255 ai->Addr.Block.freed_at = VG_(null_ExeContext)();; 1256 return True; 1257 } 1258 } 1259 return False; 1260 } 1261 1262 1263 static Bool mempool_block_maybe_describe( Addr a, Bool is_metapool, 1264 /*OUT*/AddrInfo* ai ) 1265 { 1266 MC_Mempool* mp; 1267 tl_assert( MC_(mempool_list) ); 1268 1269 VG_(HT_ResetIter)( MC_(mempool_list) ); 1270 while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) { 1271 if (mp->chunks != NULL && mp->metapool == is_metapool) { 1272 MC_Chunk* mc; 1273 VG_(HT_ResetIter)(mp->chunks); 1274 while ( (mc = VG_(HT_Next)(mp->chunks)) ) { 1275 if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) { 1276 ai->tag = Addr_Block; 1277 ai->Addr.Block.block_kind = Block_MempoolChunk; 1278 ai->Addr.Block.block_desc = "block"; 1279 ai->Addr.Block.block_szB = mc->szB; 1280 ai->Addr.Block.rwoffset = (Word)a - (Word)mc->data; 1281 ai->Addr.Block.allocated_at = MC_(allocated_at)(mc); 1282 VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo); 1283 ai->Addr.Block.freed_at = MC_(freed_at)(mc); 1284 return True; 1285 } 1286 } 1287 } 1288 } 1289 return False; 1290 } 1291 1292 1293 /*------------------------------------------------------------*/ 1294 /*--- Suppressions ---*/ 1295 /*------------------------------------------------------------*/ 1296 1297 typedef 1298 enum { 1299 ParamSupp, // Bad syscall params 1300 UserSupp, // Errors arising from client-request checks 1301 CoreMemSupp, // Memory errors in core (pthread ops, signal handling) 1302 1303 // Undefined value errors of given size 1304 Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, Value32Supp, 1305 1306 // Undefined value error in conditional. 1307 CondSupp, 1308 1309 // Unaddressable read/write attempt at given size 1310 Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp, 1311 1312 JumpSupp, // Jump to unaddressable target 1313 FreeSupp, // Invalid or mismatching free 1314 OverlapSupp, // Overlapping blocks in memcpy(), strcpy(), etc 1315 LeakSupp, // Something to be suppressed in a leak check. 1316 MempoolSupp, // Memory pool suppression. 1317 FishyValueSupp,// Fishy value suppression. 1318 } 1319 MC_SuppKind; 1320 1321 Bool MC_(is_recognised_suppression) ( const HChar* name, Supp* su ) 1322 { 1323 SuppKind skind; 1324 1325 if (VG_STREQ(name, "Param")) skind = ParamSupp; 1326 else if (VG_STREQ(name, "User")) skind = UserSupp; 1327 else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp; 1328 else if (VG_STREQ(name, "Addr1")) skind = Addr1Supp; 1329 else if (VG_STREQ(name, "Addr2")) skind = Addr2Supp; 1330 else if (VG_STREQ(name, "Addr4")) skind = Addr4Supp; 1331 else if (VG_STREQ(name, "Addr8")) skind = Addr8Supp; 1332 else if (VG_STREQ(name, "Addr16")) skind = Addr16Supp; 1333 else if (VG_STREQ(name, "Addr32")) skind = Addr32Supp; 1334 else if (VG_STREQ(name, "Jump")) skind = JumpSupp; 1335 else if (VG_STREQ(name, "Free")) skind = FreeSupp; 1336 else if (VG_STREQ(name, "Leak")) skind = LeakSupp; 1337 else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp; 1338 else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp; 1339 else if (VG_STREQ(name, "Cond")) skind = CondSupp; 1340 else if (VG_STREQ(name, "Value0")) skind = CondSupp; /* backwards compat */ 1341 else if (VG_STREQ(name, "Value1")) skind = Value1Supp; 1342 else if (VG_STREQ(name, "Value2")) skind = Value2Supp; 1343 else if (VG_STREQ(name, "Value4")) skind = Value4Supp; 1344 else if (VG_STREQ(name, "Value8")) skind = Value8Supp; 1345 else if (VG_STREQ(name, "Value16")) skind = Value16Supp; 1346 else if (VG_STREQ(name, "Value32")) skind = Value32Supp; 1347 else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp; 1348 else 1349 return False; 1350 1351 VG_(set_supp_kind)(su, skind); 1352 return True; 1353 } 1354 1355 typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra; 1356 1357 struct _MC_LeakSuppExtra { 1358 UInt match_leak_kinds; 1359 1360 /* Maintains nr of blocks and bytes suppressed with this suppression 1361 during the leak search identified by leak_search_gen. 1362 blocks_suppressed and bytes_suppressed are reset to 0 when 1363 used the first time during a leak search. */ 1364 SizeT blocks_suppressed; 1365 SizeT bytes_suppressed; 1366 UInt leak_search_gen; 1367 }; 1368 1369 typedef struct { 1370 const HChar *function_name; 1371 const HChar *argument_name; 1372 } MC_FishyValueExtra; 1373 1374 Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp, 1375 SizeT* nBufp, Int* lineno, Supp *su ) 1376 { 1377 Bool eof; 1378 Int i; 1379 1380 if (VG_(get_supp_kind)(su) == ParamSupp) { 1381 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno ); 1382 if (eof) return False; 1383 VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp)); 1384 } else if (VG_(get_supp_kind)(su) == LeakSupp) { 1385 // We might have the optional match-leak-kinds line 1386 MC_LeakSuppExtra* lse; 1387 lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra)); 1388 lse->match_leak_kinds = MC_(all_Reachedness)(); 1389 lse->blocks_suppressed = 0; 1390 lse->bytes_suppressed = 0; 1391 lse->leak_search_gen = 0; 1392 VG_(set_supp_extra)(su, lse); // By default, all kinds will match. 1393 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno ); 1394 if (eof) return True; // old LeakSupp style, no match-leak-kinds line. 1395 if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) { 1396 i = 17; 1397 while ((*bufpp)[i] && VG_(isspace)((*bufpp)[i])) 1398 i++; 1399 if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens), 1400 True/*allow_all*/, 1401 (*bufpp)+i, &lse->match_leak_kinds)) { 1402 return False; 1403 } 1404 } else { 1405 return False; // unknown extra line. 1406 } 1407 } else if (VG_(get_supp_kind)(su) == FishyValueSupp) { 1408 MC_FishyValueExtra *extra; 1409 HChar *p, *function_name, *argument_name = NULL; 1410 1411 eof = VG_(get_line) ( fd, bufpp, nBufp, lineno ); 1412 if (eof) return True; 1413 1414 // The suppression string is: function_name(argument_name) 1415 function_name = VG_(strdup)("mv.resi.4", *bufpp); 1416 p = VG_(strchr)(function_name, '('); 1417 if (p != NULL) { 1418 *p++ = '\0'; 1419 argument_name = p; 1420 p = VG_(strchr)(p, ')'); 1421 if (p != NULL) 1422 *p = '\0'; 1423 } 1424 if (p == NULL) { // malformed suppression string 1425 VG_(free)(function_name); 1426 return False; 1427 } 1428 1429 extra = VG_(malloc)("mc.resi.3", sizeof *extra); 1430 extra->function_name = function_name; 1431 extra->argument_name = argument_name; 1432 1433 VG_(set_supp_extra)(su, extra); 1434 } 1435 return True; 1436 } 1437 1438 Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su ) 1439 { 1440 Int su_szB; 1441 MC_Error* extra = VG_(get_error_extra)(err); 1442 ErrorKind ekind = VG_(get_error_kind)(err); 1443 1444 switch (VG_(get_supp_kind)(su)) { 1445 case ParamSupp: 1446 return ((ekind == Err_RegParam || ekind == Err_MemParam) 1447 && VG_STREQ(VG_(get_error_string)(err), 1448 VG_(get_supp_string)(su))); 1449 1450 case UserSupp: 1451 return (ekind == Err_User); 1452 1453 case CoreMemSupp: 1454 return (ekind == Err_CoreMem 1455 && VG_STREQ(VG_(get_error_string)(err), 1456 VG_(get_supp_string)(su))); 1457 1458 case Value1Supp: su_szB = 1; goto value_case; 1459 case Value2Supp: su_szB = 2; goto value_case; 1460 case Value4Supp: su_szB = 4; goto value_case; 1461 case Value8Supp: su_szB = 8; goto value_case; 1462 case Value16Supp:su_szB =16; goto value_case; 1463 case Value32Supp:su_szB =32; goto value_case; 1464 value_case: 1465 return (ekind == Err_Value && extra->Err.Value.szB == su_szB); 1466 1467 case CondSupp: 1468 return (ekind == Err_Cond); 1469 1470 case Addr1Supp: su_szB = 1; goto addr_case; 1471 case Addr2Supp: su_szB = 2; goto addr_case; 1472 case Addr4Supp: su_szB = 4; goto addr_case; 1473 case Addr8Supp: su_szB = 8; goto addr_case; 1474 case Addr16Supp:su_szB =16; goto addr_case; 1475 case Addr32Supp:su_szB =32; goto addr_case; 1476 addr_case: 1477 return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB); 1478 1479 case JumpSupp: 1480 return (ekind == Err_Jump); 1481 1482 case FreeSupp: 1483 return (ekind == Err_Free || ekind == Err_FreeMismatch); 1484 1485 case OverlapSupp: 1486 return (ekind == Err_Overlap); 1487 1488 case LeakSupp: 1489 if (ekind == Err_Leak) { 1490 MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su); 1491 if (lse->leak_search_gen != MC_(leak_search_gen)) { 1492 // First time we see this suppression during this leak search. 1493 // => reset the counters to 0. 1494 lse->blocks_suppressed = 0; 1495 lse->bytes_suppressed = 0; 1496 lse->leak_search_gen = MC_(leak_search_gen); 1497 } 1498 return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds); 1499 } else 1500 return False; 1501 1502 case MempoolSupp: 1503 return (ekind == Err_IllegalMempool); 1504 1505 case FishyValueSupp: { 1506 MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su); 1507 1508 return (ekind == Err_FishyValue) && 1509 VG_STREQ(extra->Err.FishyValue.function_name, 1510 supp_extra->function_name) && 1511 VG_STREQ(extra->Err.FishyValue.argument_name, 1512 supp_extra->argument_name); 1513 } 1514 1515 default: 1516 VG_(printf)("Error:\n" 1517 " unknown suppression type %d\n", 1518 VG_(get_supp_kind)(su)); 1519 VG_(tool_panic)("unknown suppression type in " 1520 "MC_(error_matches_suppression)"); 1521 } 1522 } 1523 1524 const HChar* MC_(get_error_name) ( const Error* err ) 1525 { 1526 switch (VG_(get_error_kind)(err)) { 1527 case Err_RegParam: return "Param"; 1528 case Err_MemParam: return "Param"; 1529 case Err_User: return "User"; 1530 case Err_FreeMismatch: return "Free"; 1531 case Err_IllegalMempool: return "Mempool"; 1532 case Err_Free: return "Free"; 1533 case Err_Jump: return "Jump"; 1534 case Err_CoreMem: return "CoreMem"; 1535 case Err_Overlap: return "Overlap"; 1536 case Err_Leak: return "Leak"; 1537 case Err_Cond: return "Cond"; 1538 case Err_FishyValue: return "FishyValue"; 1539 case Err_Addr: { 1540 MC_Error* extra = VG_(get_error_extra)(err); 1541 switch ( extra->Err.Addr.szB ) { 1542 case 1: return "Addr1"; 1543 case 2: return "Addr2"; 1544 case 4: return "Addr4"; 1545 case 8: return "Addr8"; 1546 case 16: return "Addr16"; 1547 case 32: return "Addr32"; 1548 default: VG_(tool_panic)("unexpected size for Addr"); 1549 } 1550 } 1551 case Err_Value: { 1552 MC_Error* extra = VG_(get_error_extra)(err); 1553 switch ( extra->Err.Value.szB ) { 1554 case 1: return "Value1"; 1555 case 2: return "Value2"; 1556 case 4: return "Value4"; 1557 case 8: return "Value8"; 1558 case 16: return "Value16"; 1559 case 32: return "Value32"; 1560 default: VG_(tool_panic)("unexpected size for Value"); 1561 } 1562 } 1563 default: VG_(tool_panic)("get_error_name: unexpected type"); 1564 } 1565 } 1566 1567 SizeT MC_(get_extra_suppression_info) ( const Error* err, 1568 /*OUT*/HChar* buf, Int nBuf ) 1569 { 1570 ErrorKind ekind = VG_(get_error_kind)(err); 1571 tl_assert(buf); 1572 tl_assert(nBuf >= 1); 1573 1574 if (Err_RegParam == ekind || Err_MemParam == ekind) { 1575 const HChar* errstr = VG_(get_error_string)(err); 1576 tl_assert(errstr); 1577 return VG_(snprintf)(buf, nBuf, "%s", errstr); 1578 } else if (Err_Leak == ekind) { 1579 MC_Error* extra = VG_(get_error_extra)(err); 1580 return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s", 1581 pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state)); 1582 } else if (Err_FishyValue == ekind) { 1583 MC_Error* extra = VG_(get_error_extra)(err); 1584 return VG_(snprintf) (buf, nBuf, "%s(%s)", 1585 extra->Err.FishyValue.function_name, 1586 extra->Err.FishyValue.argument_name); 1587 } else { 1588 buf[0] = '\0'; 1589 return 0; 1590 } 1591 } 1592 1593 SizeT MC_(print_extra_suppression_use) ( const Supp *su, 1594 /*OUT*/HChar *buf, Int nBuf ) 1595 { 1596 tl_assert(nBuf >= 1); 1597 1598 if (VG_(get_supp_kind)(su) == LeakSupp) { 1599 MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su); 1600 1601 if (lse->leak_search_gen == MC_(leak_search_gen) 1602 && lse->blocks_suppressed > 0) { 1603 return VG_(snprintf) (buf, nBuf, 1604 "suppressed: %'lu bytes in %'lu blocks", 1605 lse->bytes_suppressed, 1606 lse->blocks_suppressed); 1607 } 1608 } 1609 1610 buf[0] = '\0'; 1611 return 0; 1612 } 1613 1614 void MC_(update_extra_suppression_use) ( const Error* err, const Supp* su) 1615 { 1616 if (VG_(get_supp_kind)(su) == LeakSupp) { 1617 MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su); 1618 MC_Error* extra = VG_(get_error_extra)(err); 1619 1620 tl_assert (lse->leak_search_gen == MC_(leak_search_gen)); 1621 lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks; 1622 lse->bytes_suppressed 1623 += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB; 1624 } 1625 } 1626 1627 /*--------------------------------------------------------------------*/ 1628 /*--- end mc_errors.c ---*/ 1629 /*--------------------------------------------------------------------*/ 1630