Home | History | Annotate | Download | only in memcheck
      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-2015 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    just_below_esp = is_just_below_ESP( VG_(get_SP)(tid), a );
    750 
    751    /* If this is caused by an access immediately below %ESP, and the
    752       user asks nicely, we just ignore it. */
    753    if (MC_(clo_workaround_gcc296_bugs) && just_below_esp)
    754       return;
    755 
    756    extra.Err.Addr.isWrite   = isWrite;
    757    extra.Err.Addr.szB       = szB;
    758    extra.Err.Addr.maybe_gcc = just_below_esp;
    759    extra.Err.Addr.ai.tag    = Addr_Undescribed;
    760    VG_(maybe_record_error)( tid, Err_Addr, a, /*s*/NULL, &extra );
    761 }
    762 
    763 void MC_(record_value_error) ( ThreadId tid, Int szB, UInt otag )
    764 {
    765    MC_Error extra;
    766    tl_assert( MC_(clo_mc_level) >= 2 );
    767    if (otag > 0)
    768       tl_assert( MC_(clo_mc_level) == 3 );
    769    extra.Err.Value.szB       = szB;
    770    extra.Err.Value.otag      = otag;
    771    extra.Err.Value.origin_ec = NULL;  /* Filled in later */
    772    VG_(maybe_record_error)( tid, Err_Value, /*addr*/0, /*s*/NULL, &extra );
    773 }
    774 
    775 void MC_(record_cond_error) ( ThreadId tid, UInt otag )
    776 {
    777    MC_Error extra;
    778    tl_assert( MC_(clo_mc_level) >= 2 );
    779    if (otag > 0)
    780       tl_assert( MC_(clo_mc_level) == 3 );
    781    extra.Err.Cond.otag      = otag;
    782    extra.Err.Cond.origin_ec = NULL;  /* Filled in later */
    783    VG_(maybe_record_error)( tid, Err_Cond, /*addr*/0, /*s*/NULL, &extra );
    784 }
    785 
    786 /* --- Called from non-generated code --- */
    787 
    788 /* This is for memory errors in signal-related memory. */
    789 void MC_(record_core_mem_error) ( ThreadId tid, const HChar* msg )
    790 {
    791    VG_(maybe_record_error)( tid, Err_CoreMem, /*addr*/0, msg, /*extra*/NULL );
    792 }
    793 
    794 void MC_(record_regparam_error) ( ThreadId tid, const HChar* msg, UInt otag )
    795 {
    796    MC_Error extra;
    797    tl_assert(VG_INVALID_THREADID != tid);
    798    if (otag > 0)
    799       tl_assert( MC_(clo_mc_level) == 3 );
    800    extra.Err.RegParam.otag      = otag;
    801    extra.Err.RegParam.origin_ec = NULL;  /* Filled in later */
    802    VG_(maybe_record_error)( tid, Err_RegParam, /*addr*/0, msg, &extra );
    803 }
    804 
    805 void MC_(record_memparam_error) ( ThreadId tid, Addr a,
    806                                   Bool isAddrErr, const HChar* msg, UInt otag )
    807 {
    808    MC_Error extra;
    809    tl_assert(VG_INVALID_THREADID != tid);
    810    if (!isAddrErr)
    811       tl_assert( MC_(clo_mc_level) >= 2 );
    812    if (otag != 0) {
    813       tl_assert( MC_(clo_mc_level) == 3 );
    814       tl_assert( !isAddrErr );
    815    }
    816    extra.Err.MemParam.isAddrErr = isAddrErr;
    817    extra.Err.MemParam.ai.tag    = Addr_Undescribed;
    818    extra.Err.MemParam.otag      = otag;
    819    extra.Err.MemParam.origin_ec = NULL;  /* Filled in later */
    820    VG_(maybe_record_error)( tid, Err_MemParam, a, msg, &extra );
    821 }
    822 
    823 void MC_(record_jump_error) ( ThreadId tid, Addr a )
    824 {
    825    MC_Error extra;
    826    tl_assert(VG_INVALID_THREADID != tid);
    827    extra.Err.Jump.ai.tag = Addr_Undescribed;
    828    VG_(maybe_record_error)( tid, Err_Jump, a, /*s*/NULL, &extra );
    829 }
    830 
    831 void MC_(record_free_error) ( ThreadId tid, Addr a )
    832 {
    833    MC_Error extra;
    834    tl_assert(VG_INVALID_THREADID != tid);
    835    extra.Err.Free.ai.tag = Addr_Undescribed;
    836    VG_(maybe_record_error)( tid, Err_Free, a, /*s*/NULL, &extra );
    837 }
    838 
    839 void MC_(record_freemismatch_error) ( ThreadId tid, MC_Chunk* mc )
    840 {
    841    MC_Error extra;
    842    AddrInfo* ai = &extra.Err.FreeMismatch.ai;
    843    tl_assert(VG_INVALID_THREADID != tid);
    844    ai->tag = Addr_Block;
    845    ai->Addr.Block.block_kind = Block_Mallocd;  // Nb: Not 'Block_Freed'
    846    ai->Addr.Block.block_desc = "block";
    847    ai->Addr.Block.block_szB  = mc->szB;
    848    ai->Addr.Block.rwoffset   = 0;
    849    ai->Addr.Block.allocated_at = MC_(allocated_at) (mc);
    850    VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
    851    ai->Addr.Block.freed_at = MC_(freed_at) (mc);
    852    VG_(maybe_record_error)( tid, Err_FreeMismatch, mc->data, /*s*/NULL,
    853                             &extra );
    854 }
    855 
    856 void MC_(record_illegal_mempool_error) ( ThreadId tid, Addr a )
    857 {
    858    MC_Error extra;
    859    tl_assert(VG_INVALID_THREADID != tid);
    860    extra.Err.IllegalMempool.ai.tag = Addr_Undescribed;
    861    VG_(maybe_record_error)( tid, Err_IllegalMempool, a, /*s*/NULL, &extra );
    862 }
    863 
    864 void MC_(record_overlap_error) ( ThreadId tid, const HChar* function,
    865                                  Addr src, Addr dst, SizeT szB )
    866 {
    867    MC_Error extra;
    868    tl_assert(VG_INVALID_THREADID != tid);
    869    extra.Err.Overlap.src = src;
    870    extra.Err.Overlap.dst = dst;
    871    extra.Err.Overlap.szB = szB;
    872    VG_(maybe_record_error)(
    873       tid, Err_Overlap, /*addr*/0, /*s*/function, &extra );
    874 }
    875 
    876 Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
    877                               UInt n_total_records, LossRecord* lr,
    878                               Bool print_record, Bool count_error )
    879 {
    880    MC_Error extra;
    881    extra.Err.Leak.n_this_record   = n_this_record;
    882    extra.Err.Leak.n_total_records = n_total_records;
    883    extra.Err.Leak.lr              = lr;
    884    return
    885    VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
    886                        lr->key.allocated_at, print_record,
    887                        /*allow_GDB_attach*/False, count_error );
    888 }
    889 
    890 Bool MC_(record_fishy_value_error) ( ThreadId tid, const HChar *function_name,
    891                                      const HChar *argument_name, SizeT value)
    892 {
    893    MC_Error extra;
    894 
    895    tl_assert(VG_INVALID_THREADID != tid);
    896 
    897    if ((SSizeT)value >= 0) return False;  // not a fishy value
    898 
    899    extra.Err.FishyValue.function_name = function_name;
    900    extra.Err.FishyValue.argument_name = argument_name;
    901    extra.Err.FishyValue.value = value;
    902 
    903    VG_(maybe_record_error)(
    904       tid, Err_FishyValue, /*addr*/0, /*s*/NULL, &extra );
    905 
    906    return True;
    907 }
    908 
    909 void MC_(record_user_error) ( ThreadId tid, Addr a,
    910                               Bool isAddrErr, UInt otag )
    911 {
    912    MC_Error extra;
    913    if (otag != 0) {
    914       tl_assert(!isAddrErr);
    915       tl_assert( MC_(clo_mc_level) == 3 );
    916    }
    917    if (!isAddrErr) {
    918       tl_assert( MC_(clo_mc_level) >= 2 );
    919    }
    920    tl_assert(VG_INVALID_THREADID != tid);
    921    extra.Err.User.isAddrErr = isAddrErr;
    922    extra.Err.User.ai.tag    = Addr_Undescribed;
    923    extra.Err.User.otag      = otag;
    924    extra.Err.User.origin_ec = NULL;  /* Filled in later */
    925    VG_(maybe_record_error)( tid, Err_User, a, /*s*/NULL, &extra );
    926 }
    927 
    928 /*------------------------------------------------------------*/
    929 /*--- Other error operations                               ---*/
    930 /*------------------------------------------------------------*/
    931 
    932 /* Compare error contexts, to detect duplicates.  Note that if they
    933    are otherwise the same, the faulting addrs and associated rwoffsets
    934    are allowed to be different.  */
    935 Bool MC_(eq_Error) ( VgRes res, const Error* e1, const Error* e2 )
    936 {
    937    MC_Error* extra1 = VG_(get_error_extra)(e1);
    938    MC_Error* extra2 = VG_(get_error_extra)(e2);
    939 
    940    /* Guaranteed by calling function */
    941    tl_assert(VG_(get_error_kind)(e1) == VG_(get_error_kind)(e2));
    942 
    943    switch (VG_(get_error_kind)(e1)) {
    944       case Err_CoreMem: {
    945          const HChar *e1s, *e2s;
    946          e1s = VG_(get_error_string)(e1);
    947          e2s = VG_(get_error_string)(e2);
    948          if (e1s == e2s)                   return True;
    949          if (VG_STREQ(e1s, e2s))           return True;
    950          return False;
    951       }
    952 
    953       case Err_RegParam:
    954          return VG_STREQ(VG_(get_error_string)(e1), VG_(get_error_string)(e2));
    955 
    956       // Perhaps we should also check the addrinfo.akinds for equality.
    957       // That would result in more error reports, but only in cases where
    958       // a register contains uninitialised bytes and points to memory
    959       // containing uninitialised bytes.  Currently, the 2nd of those to be
    960       // detected won't be reported.  That is (nearly?) always the memory
    961       // error, which is good.
    962       case Err_MemParam:
    963          if (!VG_STREQ(VG_(get_error_string)(e1),
    964                        VG_(get_error_string)(e2))) return False;
    965          // fall through
    966       case Err_User:
    967          return ( extra1->Err.User.isAddrErr == extra2->Err.User.isAddrErr
    968                 ? True : False );
    969 
    970       case Err_Free:
    971       case Err_FreeMismatch:
    972       case Err_Jump:
    973       case Err_IllegalMempool:
    974       case Err_Overlap:
    975       case Err_Cond:
    976          return True;
    977 
    978       case Err_FishyValue:
    979          return VG_STREQ(extra1->Err.FishyValue.function_name,
    980                          extra2->Err.FishyValue.function_name) &&
    981                 VG_STREQ(extra1->Err.FishyValue.argument_name,
    982                          extra2->Err.FishyValue.argument_name);
    983 
    984       case Err_Addr:
    985          return ( extra1->Err.Addr.szB == extra2->Err.Addr.szB
    986                 ? True : False );
    987 
    988       case Err_Value:
    989          return ( extra1->Err.Value.szB == extra2->Err.Value.szB
    990                 ? True : False );
    991 
    992       case Err_Leak:
    993          VG_(tool_panic)("Shouldn't get Err_Leak in mc_eq_Error,\n"
    994                          "since it's handled with VG_(unique_error)()!");
    995 
    996       default:
    997          VG_(printf)("Error:\n  unknown error code %d\n",
    998                      VG_(get_error_kind)(e1));
    999          VG_(tool_panic)("unknown error code in mc_eq_Error");
   1000    }
   1001 }
   1002 
   1003 /* Functions used when searching MC_Chunk lists */
   1004 static
   1005 Bool addr_is_in_MC_Chunk_default_REDZONE_SZB(MC_Chunk* mc, Addr a)
   1006 {
   1007    return VG_(addr_is_in_block)( a, mc->data, mc->szB,
   1008                                  MC_(Malloc_Redzone_SzB) );
   1009 }
   1010 static
   1011 Bool addr_is_in_MC_Chunk_with_REDZONE_SZB(MC_Chunk* mc, Addr a, SizeT rzB)
   1012 {
   1013    return VG_(addr_is_in_block)( a, mc->data, mc->szB,
   1014                                  rzB );
   1015 }
   1016 
   1017 // Forward declarations
   1018 static Bool client_block_maybe_describe( Addr a, AddrInfo* ai );
   1019 static Bool mempool_block_maybe_describe( Addr a, AddrInfo* ai );
   1020 
   1021 
   1022 /* Describe an address as best you can, for error messages,
   1023    putting the result in ai. */
   1024 static void describe_addr ( Addr a, /*OUT*/AddrInfo* ai )
   1025 {
   1026    MC_Chunk*  mc;
   1027 
   1028    tl_assert(Addr_Undescribed == ai->tag);
   1029 
   1030    /* -- Perhaps it's a user-named block? -- */
   1031    if (client_block_maybe_describe( a, ai )) {
   1032       return;
   1033    }
   1034    /* -- Perhaps it's in mempool block? -- */
   1035    if (mempool_block_maybe_describe( a, ai )) {
   1036       return;
   1037    }
   1038    /* Blocks allocated by memcheck malloc functions are either
   1039       on the recently freed list or on the malloc-ed list.
   1040       Custom blocks can be on both : a recently freed block might
   1041       have been just re-allocated.
   1042       So, first search the malloc-ed block, as the most recent
   1043       block is the probable cause of error.
   1044       We however detect and report that this is a recently re-allocated
   1045       block. */
   1046    /* -- Search for a currently malloc'd block which might bracket it. -- */
   1047    VG_(HT_ResetIter)(MC_(malloc_list));
   1048    while ( (mc = VG_(HT_Next)(MC_(malloc_list))) ) {
   1049       if (addr_is_in_MC_Chunk_default_REDZONE_SZB(mc, a)) {
   1050          ai->tag = Addr_Block;
   1051          ai->Addr.Block.block_kind = Block_Mallocd;
   1052          if (MC_(get_freed_block_bracketting)( a ))
   1053             ai->Addr.Block.block_desc = "recently re-allocated block";
   1054          else
   1055             ai->Addr.Block.block_desc = "block";
   1056          ai->Addr.Block.block_szB  = mc->szB;
   1057          ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
   1058          ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
   1059          VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
   1060          ai->Addr.Block.freed_at = MC_(freed_at)(mc);
   1061          return;
   1062       }
   1063    }
   1064    /* -- Search for a recently freed block which might bracket it. -- */
   1065    mc = MC_(get_freed_block_bracketting)( a );
   1066    if (mc) {
   1067       ai->tag = Addr_Block;
   1068       ai->Addr.Block.block_kind = Block_Freed;
   1069       ai->Addr.Block.block_desc = "block";
   1070       ai->Addr.Block.block_szB  = mc->szB;
   1071       ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
   1072       ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
   1073       VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
   1074       ai->Addr.Block.freed_at = MC_(freed_at)(mc);
   1075       return;
   1076    }
   1077 
   1078    /* No block found. Search a non-heap block description. */
   1079    VG_(describe_addr) (a, ai);
   1080 }
   1081 
   1082 void MC_(pp_describe_addr) ( Addr a )
   1083 {
   1084    AddrInfo ai;
   1085 
   1086    ai.tag = Addr_Undescribed;
   1087    describe_addr (a, &ai);
   1088    VG_(pp_addrinfo_mc) (a, &ai, /* maybe_gcc */ False);
   1089    VG_(clear_addrinfo) (&ai);
   1090 }
   1091 
   1092 /* Fill in *origin_ec as specified by otag, or NULL it out if otag
   1093    does not refer to a known origin. */
   1094 static void update_origin ( /*OUT*/ExeContext** origin_ec,
   1095                             UInt otag )
   1096 {
   1097    UInt ecu = otag & ~3;
   1098    *origin_ec = NULL;
   1099    if (VG_(is_plausible_ECU)(ecu)) {
   1100       *origin_ec = VG_(get_ExeContext_from_ECU)( ecu );
   1101    }
   1102 }
   1103 
   1104 /* Updates the copy with address info if necessary (but not for all errors). */
   1105 UInt MC_(update_Error_extra)( const Error* err )
   1106 {
   1107    MC_Error* extra = VG_(get_error_extra)(err);
   1108 
   1109    switch (VG_(get_error_kind)(err)) {
   1110    // These ones don't have addresses associated with them, and so don't
   1111    // need any updating.
   1112    case Err_CoreMem:
   1113    //case Err_Value:
   1114    //case Err_Cond:
   1115    case Err_Overlap:
   1116    case Err_FishyValue:
   1117    // For Err_Leaks the returned size does not matter -- they are always
   1118    // shown with VG_(unique_error)() so they 'extra' not copied.  But
   1119    // we make it consistent with the others.
   1120    case Err_Leak:
   1121       return sizeof(MC_Error);
   1122 
   1123    // For value errors, get the ExeContext corresponding to the
   1124    // origin tag.  Note that it is a kludge to assume that
   1125    // a length-1 trace indicates a stack origin.  FIXME.
   1126    case Err_Value:
   1127       update_origin( &extra->Err.Value.origin_ec,
   1128                      extra->Err.Value.otag );
   1129       return sizeof(MC_Error);
   1130    case Err_Cond:
   1131       update_origin( &extra->Err.Cond.origin_ec,
   1132                      extra->Err.Cond.otag );
   1133       return sizeof(MC_Error);
   1134    case Err_RegParam:
   1135       update_origin( &extra->Err.RegParam.origin_ec,
   1136                      extra->Err.RegParam.otag );
   1137       return sizeof(MC_Error);
   1138 
   1139    // These ones always involve a memory address.
   1140    case Err_Addr:
   1141       describe_addr ( VG_(get_error_address)(err),
   1142                       &extra->Err.Addr.ai );
   1143       return sizeof(MC_Error);
   1144    case Err_MemParam:
   1145       describe_addr ( VG_(get_error_address)(err),
   1146                       &extra->Err.MemParam.ai );
   1147       update_origin( &extra->Err.MemParam.origin_ec,
   1148                      extra->Err.MemParam.otag );
   1149       return sizeof(MC_Error);
   1150    case Err_Jump:
   1151       describe_addr ( VG_(get_error_address)(err),
   1152                       &extra->Err.Jump.ai );
   1153       return sizeof(MC_Error);
   1154    case Err_User:
   1155       describe_addr ( VG_(get_error_address)(err),
   1156                       &extra->Err.User.ai );
   1157       update_origin( &extra->Err.User.origin_ec,
   1158                      extra->Err.User.otag );
   1159       return sizeof(MC_Error);
   1160    case Err_Free:
   1161       describe_addr ( VG_(get_error_address)(err),
   1162                       &extra->Err.Free.ai );
   1163       return sizeof(MC_Error);
   1164    case Err_IllegalMempool:
   1165       describe_addr ( VG_(get_error_address)(err),
   1166                       &extra->Err.IllegalMempool.ai );
   1167       return sizeof(MC_Error);
   1168 
   1169    // Err_FreeMismatches have already had their address described;  this is
   1170    // possible because we have the MC_Chunk on hand when the error is
   1171    // detected.  However, the address may be part of a user block, and if so
   1172    // we override the pre-determined description with a user block one.
   1173    case Err_FreeMismatch: {
   1174       tl_assert(extra && Block_Mallocd ==
   1175                 extra->Err.FreeMismatch.ai.Addr.Block.block_kind);
   1176       (void)client_block_maybe_describe( VG_(get_error_address)(err),
   1177                                         &extra->Err.FreeMismatch.ai );
   1178       return sizeof(MC_Error);
   1179    }
   1180 
   1181    default: VG_(tool_panic)("mc_update_extra: bad errkind");
   1182    }
   1183 }
   1184 
   1185 
   1186 static Bool client_block_maybe_describe( Addr a,
   1187                                          /*OUT*/AddrInfo* ai )
   1188 {
   1189    UWord      i;
   1190    CGenBlock* cgbs = NULL;
   1191    UWord      cgb_used = 0;
   1192 
   1193    MC_(get_ClientBlock_array)( &cgbs, &cgb_used );
   1194    if (cgbs == NULL)
   1195       tl_assert(cgb_used == 0);
   1196 
   1197    /* Perhaps it's a general block ? */
   1198    for (i = 0; i < cgb_used; i++) {
   1199       if (cgbs[i].start == 0 && cgbs[i].size == 0)
   1200          continue;
   1201       // Use zero as the redzone for client blocks.
   1202       if (VG_(addr_is_in_block)(a, cgbs[i].start, cgbs[i].size, 0)) {
   1203          ai->tag = Addr_Block;
   1204          ai->Addr.Block.block_kind = Block_UserG;
   1205          ai->Addr.Block.block_desc = cgbs[i].desc;
   1206          ai->Addr.Block.block_szB  = cgbs[i].size;
   1207          ai->Addr.Block.rwoffset   = (Word)(a) - (Word)(cgbs[i].start);
   1208          ai->Addr.Block.allocated_at = cgbs[i].where;
   1209          VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
   1210          ai->Addr.Block.freed_at = VG_(null_ExeContext)();;
   1211          return True;
   1212       }
   1213    }
   1214    return False;
   1215 }
   1216 
   1217 
   1218 static Bool mempool_block_maybe_describe( Addr a,
   1219                                           /*OUT*/AddrInfo* ai )
   1220 {
   1221    MC_Mempool* mp;
   1222    tl_assert( MC_(mempool_list) );
   1223 
   1224    VG_(HT_ResetIter)( MC_(mempool_list) );
   1225    while ( (mp = VG_(HT_Next)(MC_(mempool_list))) ) {
   1226       if (mp->chunks != NULL) {
   1227          MC_Chunk* mc;
   1228          VG_(HT_ResetIter)(mp->chunks);
   1229          while ( (mc = VG_(HT_Next)(mp->chunks)) ) {
   1230             if (addr_is_in_MC_Chunk_with_REDZONE_SZB(mc, a, mp->rzB)) {
   1231                ai->tag = Addr_Block;
   1232                ai->Addr.Block.block_kind = Block_MempoolChunk;
   1233                ai->Addr.Block.block_desc = "block";
   1234                ai->Addr.Block.block_szB  = mc->szB;
   1235                ai->Addr.Block.rwoffset   = (Word)a - (Word)mc->data;
   1236                ai->Addr.Block.allocated_at = MC_(allocated_at)(mc);
   1237                VG_(initThreadInfo) (&ai->Addr.Block.alloc_tinfo);
   1238                ai->Addr.Block.freed_at = MC_(freed_at)(mc);
   1239                return True;
   1240             }
   1241          }
   1242       }
   1243    }
   1244    return False;
   1245 }
   1246 
   1247 
   1248 /*------------------------------------------------------------*/
   1249 /*--- Suppressions                                         ---*/
   1250 /*------------------------------------------------------------*/
   1251 
   1252 typedef
   1253    enum {
   1254       ParamSupp,     // Bad syscall params
   1255       UserSupp,      // Errors arising from client-request checks
   1256       CoreMemSupp,   // Memory errors in core (pthread ops, signal handling)
   1257 
   1258       // Undefined value errors of given size
   1259       Value1Supp, Value2Supp, Value4Supp, Value8Supp, Value16Supp, Value32Supp,
   1260 
   1261       // Undefined value error in conditional.
   1262       CondSupp,
   1263 
   1264       // Unaddressable read/write attempt at given size
   1265       Addr1Supp, Addr2Supp, Addr4Supp, Addr8Supp, Addr16Supp, Addr32Supp,
   1266 
   1267       JumpSupp,      // Jump to unaddressable target
   1268       FreeSupp,      // Invalid or mismatching free
   1269       OverlapSupp,   // Overlapping blocks in memcpy(), strcpy(), etc
   1270       LeakSupp,      // Something to be suppressed in a leak check.
   1271       MempoolSupp,   // Memory pool suppression.
   1272       FishyValueSupp,// Fishy value suppression.
   1273    }
   1274    MC_SuppKind;
   1275 
   1276 Bool MC_(is_recognised_suppression) ( const HChar* name, Supp* su )
   1277 {
   1278    SuppKind skind;
   1279 
   1280    if      (VG_STREQ(name, "Param"))   skind = ParamSupp;
   1281    else if (VG_STREQ(name, "User"))    skind = UserSupp;
   1282    else if (VG_STREQ(name, "CoreMem")) skind = CoreMemSupp;
   1283    else if (VG_STREQ(name, "Addr1"))   skind = Addr1Supp;
   1284    else if (VG_STREQ(name, "Addr2"))   skind = Addr2Supp;
   1285    else if (VG_STREQ(name, "Addr4"))   skind = Addr4Supp;
   1286    else if (VG_STREQ(name, "Addr8"))   skind = Addr8Supp;
   1287    else if (VG_STREQ(name, "Addr16"))  skind = Addr16Supp;
   1288    else if (VG_STREQ(name, "Addr32"))  skind = Addr32Supp;
   1289    else if (VG_STREQ(name, "Jump"))    skind = JumpSupp;
   1290    else if (VG_STREQ(name, "Free"))    skind = FreeSupp;
   1291    else if (VG_STREQ(name, "Leak"))    skind = LeakSupp;
   1292    else if (VG_STREQ(name, "Overlap")) skind = OverlapSupp;
   1293    else if (VG_STREQ(name, "Mempool")) skind = MempoolSupp;
   1294    else if (VG_STREQ(name, "Cond"))    skind = CondSupp;
   1295    else if (VG_STREQ(name, "Value0"))  skind = CondSupp; /* backwards compat */
   1296    else if (VG_STREQ(name, "Value1"))  skind = Value1Supp;
   1297    else if (VG_STREQ(name, "Value2"))  skind = Value2Supp;
   1298    else if (VG_STREQ(name, "Value4"))  skind = Value4Supp;
   1299    else if (VG_STREQ(name, "Value8"))  skind = Value8Supp;
   1300    else if (VG_STREQ(name, "Value16")) skind = Value16Supp;
   1301    else if (VG_STREQ(name, "Value32")) skind = Value32Supp;
   1302    else if (VG_STREQ(name, "FishyValue")) skind = FishyValueSupp;
   1303    else
   1304       return False;
   1305 
   1306    VG_(set_supp_kind)(su, skind);
   1307    return True;
   1308 }
   1309 
   1310 typedef struct _MC_LeakSuppExtra MC_LeakSuppExtra;
   1311 
   1312 struct _MC_LeakSuppExtra {
   1313    UInt match_leak_kinds;
   1314 
   1315    /* Maintains nr of blocks and bytes suppressed with this suppression
   1316       during the leak search identified by leak_search_gen.
   1317       blocks_suppressed and bytes_suppressed are reset to 0 when
   1318       used the first time during a leak search. */
   1319    SizeT blocks_suppressed;
   1320    SizeT bytes_suppressed;
   1321    UInt  leak_search_gen;
   1322 };
   1323 
   1324 typedef struct {
   1325    const HChar *function_name;
   1326    const HChar *argument_name;
   1327 } MC_FishyValueExtra;
   1328 
   1329 Bool MC_(read_extra_suppression_info) ( Int fd, HChar** bufpp,
   1330                                         SizeT* nBufp, Int* lineno, Supp *su )
   1331 {
   1332    Bool eof;
   1333    Int i;
   1334 
   1335    if (VG_(get_supp_kind)(su) == ParamSupp) {
   1336       eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
   1337       if (eof) return False;
   1338       VG_(set_supp_string)(su, VG_(strdup)("mc.resi.1", *bufpp));
   1339    } else if (VG_(get_supp_kind)(su) == LeakSupp) {
   1340       // We might have the optional match-leak-kinds line
   1341       MC_LeakSuppExtra* lse;
   1342       lse = VG_(malloc)("mc.resi.2", sizeof(MC_LeakSuppExtra));
   1343       lse->match_leak_kinds = MC_(all_Reachedness)();
   1344       lse->blocks_suppressed = 0;
   1345       lse->bytes_suppressed = 0;
   1346       lse->leak_search_gen = 0;
   1347       VG_(set_supp_extra)(su, lse); // By default, all kinds will match.
   1348       eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
   1349       if (eof) return True; // old LeakSupp style, no match-leak-kinds line.
   1350       if (0 == VG_(strncmp)(*bufpp, "match-leak-kinds:", 17)) {
   1351          i = 17;
   1352          while ((*bufpp)[i] && VG_(isspace((*bufpp)[i])))
   1353             i++;
   1354          if (!VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
   1355                                   True/*allow_all*/,
   1356                                   (*bufpp)+i, &lse->match_leak_kinds)) {
   1357             return False;
   1358          }
   1359       } else {
   1360          return False; // unknown extra line.
   1361       }
   1362    } else if (VG_(get_supp_kind)(su) == FishyValueSupp) {
   1363       MC_FishyValueExtra *extra;
   1364       HChar *p, *function_name, *argument_name = NULL;
   1365 
   1366       eof = VG_(get_line) ( fd, bufpp, nBufp, lineno );
   1367       if (eof) return True;
   1368 
   1369       // The suppression string is: function_name(argument_name)
   1370       function_name = VG_(strdup)("mv.resi.4", *bufpp);
   1371       p = VG_(strchr)(function_name, '(');
   1372       if (p != NULL) {
   1373          *p++ = '\0';
   1374          argument_name = p;
   1375          p = VG_(strchr)(p, ')');
   1376          if (p != NULL)
   1377             *p = '\0';
   1378       }
   1379       if (p == NULL) {    // malformed suppression string
   1380          VG_(free)(function_name);
   1381          return False;
   1382       }
   1383 
   1384       extra = VG_(malloc)("mc.resi.3", sizeof *extra);
   1385       extra->function_name = function_name;
   1386       extra->argument_name = argument_name;
   1387 
   1388       VG_(set_supp_extra)(su, extra);
   1389    }
   1390    return True;
   1391 }
   1392 
   1393 Bool MC_(error_matches_suppression) ( const Error* err, const Supp* su )
   1394 {
   1395    Int       su_szB;
   1396    MC_Error* extra = VG_(get_error_extra)(err);
   1397    ErrorKind ekind = VG_(get_error_kind )(err);
   1398 
   1399    switch (VG_(get_supp_kind)(su)) {
   1400       case ParamSupp:
   1401          return ((ekind == Err_RegParam || ekind == Err_MemParam)
   1402               && VG_STREQ(VG_(get_error_string)(err),
   1403                           VG_(get_supp_string)(su)));
   1404 
   1405       case UserSupp:
   1406          return (ekind == Err_User);
   1407 
   1408       case CoreMemSupp:
   1409          return (ekind == Err_CoreMem
   1410               && VG_STREQ(VG_(get_error_string)(err),
   1411                           VG_(get_supp_string)(su)));
   1412 
   1413       case Value1Supp: su_szB = 1; goto value_case;
   1414       case Value2Supp: su_szB = 2; goto value_case;
   1415       case Value4Supp: su_szB = 4; goto value_case;
   1416       case Value8Supp: su_szB = 8; goto value_case;
   1417       case Value16Supp:su_szB =16; goto value_case;
   1418       case Value32Supp:su_szB =32; goto value_case;
   1419       value_case:
   1420          return (ekind == Err_Value && extra->Err.Value.szB == su_szB);
   1421 
   1422       case CondSupp:
   1423          return (ekind == Err_Cond);
   1424 
   1425       case Addr1Supp: su_szB = 1; goto addr_case;
   1426       case Addr2Supp: su_szB = 2; goto addr_case;
   1427       case Addr4Supp: su_szB = 4; goto addr_case;
   1428       case Addr8Supp: su_szB = 8; goto addr_case;
   1429       case Addr16Supp:su_szB =16; goto addr_case;
   1430       case Addr32Supp:su_szB =32; goto addr_case;
   1431       addr_case:
   1432          return (ekind == Err_Addr && extra->Err.Addr.szB == su_szB);
   1433 
   1434       case JumpSupp:
   1435          return (ekind == Err_Jump);
   1436 
   1437       case FreeSupp:
   1438          return (ekind == Err_Free || ekind == Err_FreeMismatch);
   1439 
   1440       case OverlapSupp:
   1441          return (ekind == Err_Overlap);
   1442 
   1443       case LeakSupp:
   1444          if (ekind == Err_Leak) {
   1445             MC_LeakSuppExtra* lse = (MC_LeakSuppExtra*) VG_(get_supp_extra)(su);
   1446             if (lse->leak_search_gen != MC_(leak_search_gen)) {
   1447                // First time we see this suppression during this leak search.
   1448                // => reset the counters to 0.
   1449                lse->blocks_suppressed = 0;
   1450                lse->bytes_suppressed = 0;
   1451                lse->leak_search_gen = MC_(leak_search_gen);
   1452             }
   1453             return RiS(extra->Err.Leak.lr->key.state, lse->match_leak_kinds);
   1454          } else
   1455             return False;
   1456 
   1457       case MempoolSupp:
   1458          return (ekind == Err_IllegalMempool);
   1459 
   1460       case FishyValueSupp: {
   1461          MC_FishyValueExtra *supp_extra = VG_(get_supp_extra)(su);
   1462 
   1463          return (ekind == Err_FishyValue) &&
   1464                 VG_STREQ(extra->Err.FishyValue.function_name,
   1465                          supp_extra->function_name) &&
   1466                 VG_STREQ(extra->Err.FishyValue.argument_name,
   1467                          supp_extra->argument_name);
   1468       }
   1469 
   1470       default:
   1471          VG_(printf)("Error:\n"
   1472                      "  unknown suppression type %d\n",
   1473                      VG_(get_supp_kind)(su));
   1474          VG_(tool_panic)("unknown suppression type in "
   1475                          "MC_(error_matches_suppression)");
   1476    }
   1477 }
   1478 
   1479 const HChar* MC_(get_error_name) ( const Error* err )
   1480 {
   1481    switch (VG_(get_error_kind)(err)) {
   1482    case Err_RegParam:       return "Param";
   1483    case Err_MemParam:       return "Param";
   1484    case Err_User:           return "User";
   1485    case Err_FreeMismatch:   return "Free";
   1486    case Err_IllegalMempool: return "Mempool";
   1487    case Err_Free:           return "Free";
   1488    case Err_Jump:           return "Jump";
   1489    case Err_CoreMem:        return "CoreMem";
   1490    case Err_Overlap:        return "Overlap";
   1491    case Err_Leak:           return "Leak";
   1492    case Err_Cond:           return "Cond";
   1493    case Err_FishyValue:     return "FishyValue";
   1494    case Err_Addr: {
   1495       MC_Error* extra = VG_(get_error_extra)(err);
   1496       switch ( extra->Err.Addr.szB ) {
   1497       case 1:               return "Addr1";
   1498       case 2:               return "Addr2";
   1499       case 4:               return "Addr4";
   1500       case 8:               return "Addr8";
   1501       case 16:              return "Addr16";
   1502       case 32:              return "Addr32";
   1503       default:              VG_(tool_panic)("unexpected size for Addr");
   1504       }
   1505    }
   1506    case Err_Value: {
   1507       MC_Error* extra = VG_(get_error_extra)(err);
   1508       switch ( extra->Err.Value.szB ) {
   1509       case 1:               return "Value1";
   1510       case 2:               return "Value2";
   1511       case 4:               return "Value4";
   1512       case 8:               return "Value8";
   1513       case 16:              return "Value16";
   1514       case 32:              return "Value32";
   1515       default:              VG_(tool_panic)("unexpected size for Value");
   1516       }
   1517    }
   1518    default:                 VG_(tool_panic)("get_error_name: unexpected type");
   1519    }
   1520 }
   1521 
   1522 SizeT MC_(get_extra_suppression_info) ( const Error* err,
   1523                                         /*OUT*/HChar* buf, Int nBuf )
   1524 {
   1525    ErrorKind ekind = VG_(get_error_kind )(err);
   1526    tl_assert(buf);
   1527    tl_assert(nBuf >= 1);
   1528 
   1529    if (Err_RegParam == ekind || Err_MemParam == ekind) {
   1530       const HChar* errstr = VG_(get_error_string)(err);
   1531       tl_assert(errstr);
   1532       return VG_(snprintf)(buf, nBuf, "%s", errstr);
   1533    } else if (Err_Leak == ekind) {
   1534       MC_Error* extra = VG_(get_error_extra)(err);
   1535       return VG_(snprintf) (buf, nBuf, "match-leak-kinds: %s",
   1536           pp_Reachedness_for_leak_kinds(extra->Err.Leak.lr->key.state));
   1537    } else if (Err_FishyValue == ekind) {
   1538       MC_Error* extra = VG_(get_error_extra)(err);
   1539       return VG_(snprintf) (buf, nBuf, "%s(%s)",
   1540                             extra->Err.FishyValue.function_name,
   1541                             extra->Err.FishyValue.argument_name);
   1542    } else {
   1543       buf[0] = '\0';
   1544       return 0;
   1545    }
   1546 }
   1547 
   1548 SizeT MC_(print_extra_suppression_use) ( const Supp *su,
   1549                                          /*OUT*/HChar *buf, Int nBuf )
   1550 {
   1551    tl_assert(nBuf >= 1);
   1552 
   1553    if (VG_(get_supp_kind)(su) == LeakSupp) {
   1554       MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
   1555 
   1556       if (lse->leak_search_gen == MC_(leak_search_gen)
   1557           && lse->blocks_suppressed > 0) {
   1558          return VG_(snprintf) (buf, nBuf,
   1559                                "suppressed: %'lu bytes in %'lu blocks",
   1560                                lse->bytes_suppressed,
   1561                                lse->blocks_suppressed);
   1562       }
   1563    }
   1564 
   1565    buf[0] = '\0';
   1566    return 0;
   1567 }
   1568 
   1569 void MC_(update_extra_suppression_use) ( const Error* err, const Supp* su)
   1570 {
   1571    if (VG_(get_supp_kind)(su) == LeakSupp) {
   1572       MC_LeakSuppExtra *lse = (MC_LeakSuppExtra*) VG_(get_supp_extra) (su);
   1573       MC_Error* extra = VG_(get_error_extra)(err);
   1574 
   1575       tl_assert (lse->leak_search_gen == MC_(leak_search_gen));
   1576       lse->blocks_suppressed += extra->Err.Leak.lr->num_blocks;
   1577       lse->bytes_suppressed
   1578          += extra->Err.Leak.lr->szB + extra->Err.Leak.lr->indirect_szB;
   1579    }
   1580 }
   1581 
   1582 /*--------------------------------------------------------------------*/
   1583 /*--- end                                              mc_errors.c ---*/
   1584 /*--------------------------------------------------------------------*/
   1585