Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Management of error messages.                   m_errormgr.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2012 Julian Seward
     11       jseward (at) acm.org
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #include "pub_core_basics.h"
     32 #include "pub_core_vki.h"
     33 #include "pub_core_libcsetjmp.h"
     34 #include "pub_core_threadstate.h"      // For VG_N_THREADS
     35 #include "pub_core_debugger.h"
     36 #include "pub_core_debuginfo.h"
     37 #include "pub_core_errormgr.h"
     38 #include "pub_core_execontext.h"
     39 #include "pub_core_gdbserver.h"
     40 #include "pub_core_libcbase.h"
     41 #include "pub_core_libcassert.h"
     42 #include "pub_core_libcfile.h"
     43 #include "pub_core_libcprint.h"
     44 #include "pub_core_libcproc.h"         // For VG_(getpid)()
     45 #include "pub_core_seqmatch.h"
     46 #include "pub_core_mallocfree.h"
     47 #include "pub_core_options.h"
     48 #include "pub_core_stacktrace.h"
     49 #include "pub_core_tooliface.h"
     50 #include "pub_core_translate.h"        // for VG_(translate)()
     51 #include "pub_core_xarray.h"           // VG_(xaprintf) et al
     52 
     53 /*------------------------------------------------------------*/
     54 /*--- Globals                                              ---*/
     55 /*------------------------------------------------------------*/
     56 
     57 /* After this many different unsuppressed errors have been observed,
     58    be more conservative about collecting new ones. */
     59 #define M_COLLECT_ERRORS_SLOWLY_AFTER 100
     60 
     61 /* After this many different unsuppressed errors have been observed,
     62    stop collecting errors at all, and tell the user their program is
     63    evidently a steaming pile of camel dung. */
     64 #define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000
     65 
     66 /* After this many total errors have been observed, stop collecting
     67    errors at all.  Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
     68 #define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000
     69 
     70 /* The list of error contexts found, both suppressed and unsuppressed.
     71    Initially empty, and grows as errors are detected. */
     72 static Error* errors = NULL;
     73 
     74 /* The list of suppression directives, as read from the specified
     75    suppressions file.  Note that the list gets rearranged as a result
     76    of the searches done by is_suppressible_error(). */
     77 static Supp* suppressions = NULL;
     78 
     79 /* Running count of unsuppressed errors detected. */
     80 static UInt n_errs_found = 0;
     81 
     82 /* Running count of suppressed errors detected. */
     83 static UInt n_errs_suppressed = 0;
     84 
     85 /* Running count of errors shown. */
     86 static UInt n_errs_shown = 0;
     87 
     88 /* Running count of unsuppressed error contexts. */
     89 static UInt n_err_contexts = 0;
     90 
     91 /* Running count of suppressed error contexts. */
     92 static UInt n_supp_contexts = 0;
     93 
     94 
     95 /* forwards ... */
     96 static Supp* is_suppressible_error ( Error* err );
     97 
     98 static ThreadId last_tid_printed = 1;
     99 
    100 /* Stats: number of searches of the error list initiated. */
    101 static UWord em_errlist_searches = 0;
    102 
    103 /* Stats: number of comparisons done during error list
    104    searching. */
    105 static UWord em_errlist_cmps = 0;
    106 
    107 /* Stats: number of searches of the suppression list initiated. */
    108 static UWord em_supplist_searches = 0;
    109 
    110 /* Stats: number of comparisons done during suppression list
    111    searching. */
    112 static UWord em_supplist_cmps = 0;
    113 
    114 /*------------------------------------------------------------*/
    115 /*--- Error type                                           ---*/
    116 /*------------------------------------------------------------*/
    117 
    118 /* Errors.  Extensible (via the 'extra' field).  Tools can use a normal
    119    enum (with element values in the normal range (0..)) for 'ekind'.
    120    Functions for getting/setting the tool-relevant fields are in
    121    include/pub_tool_errormgr.h.
    122 
    123    When errors are found and recorded with VG_(maybe_record_error)(), all
    124    the tool must do is pass in the four parameters;  core will
    125    allocate/initialise the error record.
    126 */
    127 struct _Error {
    128    struct _Error* next;
    129    // Unique tag.  This gives the error a unique identity (handle) by
    130    // which it can be referred to afterwords.  Currently only used for
    131    // XML printing.
    132    UInt unique;
    133    // NULL if unsuppressed; or ptr to suppression record.
    134    Supp* supp;
    135    Int count;
    136 
    137    // The tool-specific part
    138    ThreadId tid;           // Initialised by core
    139    ExeContext* where;      // Initialised by core
    140    ErrorKind ekind;        // Used by ALL.  Must be in the range (0..)
    141    Addr addr;              // Used frequently
    142    Char* string;           // Used frequently
    143    void* extra;            // For any tool-specific extras
    144 };
    145 
    146 
    147 ExeContext* VG_(get_error_where) ( Error* err )
    148 {
    149    return err->where;
    150 }
    151 
    152 ErrorKind VG_(get_error_kind) ( Error* err )
    153 {
    154    return err->ekind;
    155 }
    156 
    157 Addr VG_(get_error_address) ( Error* err )
    158 {
    159    return err->addr;
    160 }
    161 
    162 Char* VG_(get_error_string) ( Error* err )
    163 {
    164    return err->string;
    165 }
    166 
    167 void* VG_(get_error_extra)  ( Error* err )
    168 {
    169    return err->extra;
    170 }
    171 
    172 UInt VG_(get_n_errs_found)( void )
    173 {
    174    return n_errs_found;
    175 }
    176 
    177 UInt VG_(get_n_errs_shown)( void )
    178 {
    179    return n_errs_shown;
    180 }
    181 
    182 /*------------------------------------------------------------*/
    183 /*--- Suppression type                                     ---*/
    184 /*------------------------------------------------------------*/
    185 
    186 /* Note: it is imperative this doesn't overlap with (0..) at all, as tools
    187  * effectively extend it by defining their own enums in the (0..) range. */
    188 typedef
    189    enum {
    190       // Nb: thread errors are a relic of the time when Valgrind's core
    191       // could detect them.  This example is left commented-out as an
    192       // example should new core errors ever be added.
    193       ThreadSupp = -1,    /* Matches ThreadErr */
    194    }
    195    CoreSuppKind;
    196 
    197 /* Max number of callers for context in a suppression. */
    198 #define VG_MAX_SUPP_CALLERS  24
    199 
    200 /* For each caller specified for a suppression, record the nature of
    201    the caller name.  Not of interest to tools. */
    202 typedef
    203    enum {
    204       NoName,     /* Error case */
    205       ObjName,    /* Name is of an shared object file. */
    206       FunName,    /* Name is of a function. */
    207       DotDotDot   /* Frame-level wildcard */
    208    }
    209    SuppLocTy;
    210 
    211 typedef
    212    struct {
    213       SuppLocTy ty;
    214       Bool      name_is_simple_str; /* True if name is a string without
    215                                        '?' and '*' wildcard characters. */
    216       Char*     name; /* NULL for NoName and DotDotDot */
    217    }
    218    SuppLoc;
    219 
    220 /* Suppressions.  Tools can get/set tool-relevant parts with functions
    221    declared in include/pub_tool_errormgr.h.  Extensible via the 'extra' field.
    222    Tools can use a normal enum (with element values in the normal range
    223    (0..)) for 'skind'. */
    224 struct _Supp {
    225    struct _Supp* next;
    226    Int count;     // The number of times this error has been suppressed.
    227    Char* sname;   // The name by which the suppression is referred to.
    228 
    229    // Length of 'callers'
    230    Int n_callers;
    231    // Array of callers, for matching stack traces.  First one (name of fn
    232    // where err occurs) is mandatory;  rest are optional.
    233    SuppLoc* callers;
    234 
    235    /* The tool-specific part */
    236    SuppKind skind;   // What kind of suppression.  Must use the range (0..).
    237    Char* string;     // String -- use is optional.  NULL by default.
    238    void* extra;      // Anything else -- use is optional.  NULL by default.
    239 };
    240 
    241 SuppKind VG_(get_supp_kind) ( Supp* su )
    242 {
    243    return su->skind;
    244 }
    245 
    246 Char* VG_(get_supp_string) ( Supp* su )
    247 {
    248    return su->string;
    249 }
    250 
    251 void* VG_(get_supp_extra)  ( Supp* su )
    252 {
    253    return su->extra;
    254 }
    255 
    256 
    257 void VG_(set_supp_kind)   ( Supp* su, SuppKind skind )
    258 {
    259    su->skind = skind;
    260 }
    261 
    262 void VG_(set_supp_string) ( Supp* su, Char* string )
    263 {
    264    su->string = string;
    265 }
    266 
    267 void VG_(set_supp_extra)  ( Supp* su, void* extra )
    268 {
    269    su->extra = extra;
    270 }
    271 
    272 
    273 /*------------------------------------------------------------*/
    274 /*--- Helper fns                                           ---*/
    275 /*------------------------------------------------------------*/
    276 
    277 // Only show core errors if the tool wants to, we're not running with -q,
    278 // and were not outputting XML.
    279 Bool VG_(showing_core_errors)(void)
    280 {
    281    return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
    282 }
    283 
    284 /* Compare errors, to detect duplicates.
    285 */
    286 static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
    287 {
    288    if (e1->ekind != e2->ekind)
    289       return False;
    290    if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
    291       return False;
    292 
    293    switch (e1->ekind) {
    294       //(example code, see comment on CoreSuppKind above)
    295       //case ThreadErr:
    296       //   vg_assert(VG_(needs).core_errors);
    297       //   return <something>
    298       default:
    299          if (VG_(needs).tool_errors) {
    300             return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
    301          } else {
    302             VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
    303                         "probably needs to be set.\n",
    304                         e1->ekind);
    305             VG_(tool_panic)("unhandled error type");
    306          }
    307    }
    308 }
    309 
    310 
    311 /* Helper functions for suppression generation: print a single line of
    312    a suppression pseudo-stack-trace, either in XML or text mode.  It's
    313    important that the behaviour of these two functions exactly
    314    corresponds.
    315 */
    316 #define ERRTXT_LEN   4096
    317 
    318 static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
    319 {
    320    static UChar buf[ERRTXT_LEN];
    321    if ( VG_(get_fnname_no_cxx_demangle) (ip, buf,  ERRTXT_LEN) ) {
    322       VG_(printf_xml)("    <sframe> <fun>%pS</fun> </sframe>\n", buf);
    323    } else
    324    if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
    325       VG_(printf_xml)("    <sframe> <obj>%pS</obj> </sframe>\n", buf);
    326    } else {
    327       VG_(printf_xml)("    <sframe> <obj>*</obj> </sframe>\n");
    328    }
    329 }
    330 
    331 static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
    332 {
    333    static UChar buf[ERRTXT_LEN];
    334    XArray* /* of HChar */ text = (XArray*)textV;
    335    if ( VG_(get_fnname_no_cxx_demangle) (ip, buf,  ERRTXT_LEN) ) {
    336       VG_(xaprintf)(text, "   fun:%s\n", buf);
    337    } else
    338    if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
    339       VG_(xaprintf)(text, "   obj:%s\n", buf);
    340    } else {
    341       VG_(xaprintf)(text, "   obj:*\n");
    342    }
    343 }
    344 
    345 /* Generate a suppression for an error, either in text or XML mode.
    346 */
    347 static void gen_suppression(Error* err)
    348 {
    349    Char        xtra[256]; /* assumed big enough (is overrun-safe) */
    350    Bool        anyXtra;
    351    Char*       name;
    352    ExeContext* ec;
    353    XArray* /* HChar */ text;
    354 
    355    const HChar* dummy_name = "insert_a_suppression_name_here";
    356 
    357    vg_assert(err);
    358 
    359    ec = VG_(get_error_where)(err);
    360    vg_assert(ec);
    361 
    362    name = VG_TDICT_CALL(tool_get_error_name, err);
    363    if (NULL == name) {
    364       VG_(umsg)("(%s does not allow error to be suppressed)\n",
    365                 VG_(details).name);
    366       return;
    367    }
    368 
    369    /* In XML mode, we also need to print the plain text version of the
    370       suppresion in a CDATA section.  What that really means is, we
    371       need to generate the plaintext version both in XML and text
    372       mode.  So generate it into TEXT. */
    373    text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
    374                       VG_(free), sizeof(HChar) );
    375    vg_assert(text);
    376 
    377    /* Ok.  Generate the plain text version into TEXT. */
    378    VG_(xaprintf)(text, "{\n");
    379    VG_(xaprintf)(text, "   <%s>\n", dummy_name);
    380    VG_(xaprintf)(text, "   %s:%s\n", VG_(details).name, name);
    381 
    382    VG_(memset)(xtra, 0, sizeof(xtra));
    383    anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
    384                            err, xtra, sizeof(xtra));
    385    vg_assert(xtra[sizeof(xtra)-1] == 0);
    386 
    387    if (anyXtra)
    388       VG_(xaprintf)(text, "   %s\n", xtra);
    389 
    390    // Print stack trace elements
    391    UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
    392    tl_assert(n_ips > 0);
    393    if (n_ips > VG_MAX_SUPP_CALLERS)
    394       n_ips = VG_MAX_SUPP_CALLERS;
    395    VG_(apply_StackTrace)(printSuppForIp_nonXML,
    396                          text,
    397                          VG_(get_ExeContext_StackTrace)(ec),
    398                          n_ips);
    399 
    400    VG_(xaprintf)(text, "}\n");
    401    // zero terminate
    402    VG_(xaprintf)(text, "%c", (HChar)0 );
    403    // VG_(printf) of text
    404 
    405    /* And now display it. */
    406    if (! VG_(clo_xml) ) {
    407 
    408       // the simple case
    409       VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
    410 
    411    } else {
    412 
    413       /* Now we have to print the XML directly.  No need to go to the
    414          effort of stuffing it in an XArray, since we won't need it
    415          again. */
    416       VG_(printf_xml)("  <suppression>\n");
    417       VG_(printf_xml)("    <sname>%s</sname>\n", dummy_name);
    418       VG_(printf_xml)(
    419                       "    <skind>%pS:%pS</skind>\n", VG_(details).name, name);
    420       if (anyXtra)
    421          VG_(printf_xml)("    <skaux>%pS</skaux>\n", xtra);
    422 
    423       // Print stack trace elements
    424       VG_(apply_StackTrace)(printSuppForIp_XML,
    425                             NULL,
    426                             VG_(get_ExeContext_StackTrace)(ec),
    427                             VG_(get_ExeContext_n_ips)(ec));
    428 
    429       // And now the cdata bit
    430       // XXX FIXME!  properly handle the case where the raw text
    431       // itself contains "]]>", as specified in Protocol 4.
    432       VG_(printf_xml)("    <rawtext>\n");
    433       VG_(printf_xml)("<![CDATA[\n");
    434       VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
    435       VG_(printf_xml)("]]>\n");
    436       VG_(printf_xml)("    </rawtext>\n");
    437       VG_(printf_xml)("  </suppression>\n");
    438 
    439    }
    440 
    441    VG_(deleteXA)(text);
    442 }
    443 
    444 
    445 /* Figure out if we want to perform a given action for this error,
    446    possibly by asking the user.
    447 */
    448 Bool VG_(is_action_requested) ( Char* action, Bool* clo )
    449 {
    450    Char ch, ch2;
    451    Int res;
    452 
    453    /* First off, we shouldn't be asking the user anything if
    454       we're in XML mode. */
    455    if (VG_(clo_xml))
    456       return False; /* That's a Nein, oder Nay as they say down here in B-W */
    457 
    458    if (*clo == False)
    459       return False;
    460 
    461    VG_(umsg)("\n");
    462 
    463   again:
    464    VG_(printf)(
    465       "==%d== "
    466       "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",
    467       VG_(getpid)(), action
    468    );
    469 
    470    res = VG_(read)(VG_(clo_input_fd), &ch, 1);
    471    if (res != 1) goto ioerror;
    472    /* res == 1 */
    473    if (ch == '\n') return False;
    474    if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y'
    475       && ch != 'C' && ch != 'c') goto again;
    476 
    477    res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
    478    if (res != 1) goto ioerror;
    479    if (ch2 != '\n') goto again;
    480 
    481    /* No, don't want to do action. */
    482    if (ch == 'n' || ch == 'N') return False;
    483    /* Yes, want to do action. */
    484    if (ch == 'y' || ch == 'Y') return True;
    485    /* No, don't want to do action, and don't ask again either. */
    486    vg_assert(ch == 'c' || ch == 'C');
    487 
    488   ioerror:
    489    *clo = False;
    490    return False;
    491 }
    492 
    493 
    494 /* Do text-mode actions on error, that is, immediately after an error
    495    is printed.  These are:
    496    * possibly, attach to a debugger
    497    * possibly, generate a suppression.
    498    Note this should not be called in XML mode!
    499 */
    500 static
    501 void do_actions_on_error(Error* err, Bool allow_db_attach)
    502 {
    503    Bool still_noisy = True;
    504 
    505    /* Should be assured by caller */
    506    vg_assert( ! VG_(clo_xml) );
    507 
    508    /* if user wants to debug from a certain error nr, then wait for gdb/vgdb */
    509    if (VG_(clo_vgdb) != Vg_VgdbNo
    510        && allow_db_attach
    511        && VG_(dyn_vgdb_error) <= n_errs_shown) {
    512       VG_(umsg)("(action on error) vgdb me ... \n");
    513       VG_(gdbserver)( err->tid );
    514       VG_(umsg)("Continuing ...\n");
    515    }
    516 
    517    /* Perhaps we want a debugger attach at this point? */
    518    /* GDBTD ??? maybe we should/could remove the below assuming the
    519       gdbserver interface is better ??? */
    520    if (allow_db_attach &&
    521        VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
    522    {
    523       if (0) VG_(printf)("starting debugger\n");
    524       VG_(start_debugger)( err->tid );
    525    }
    526    /* Or maybe we want to generate the error's suppression? */
    527    if (VG_(clo_gen_suppressions) == 2
    528        || (VG_(clo_gen_suppressions) == 1
    529            && VG_(is_action_requested)( "Print suppression", &still_noisy ))
    530       ) {
    531       gen_suppression(err);
    532    }
    533    if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
    534       VG_(clo_gen_suppressions) = 0;
    535 }
    536 
    537 
    538 /* Prints an error.  Not entirely simple because of the differences
    539    between XML and text mode output.
    540 
    541    In XML mode:
    542 
    543    * calls the tool's pre-show method, so the tool can create any
    544      preamble ahead of the message, if it wants.
    545 
    546    * prints the opening tag, and the <unique> and <tid> fields
    547 
    548    * prints the tool-specific parts of the message
    549 
    550    * if suppression generation is required, a suppression
    551 
    552    * the closing tag
    553 
    554    In text mode:
    555 
    556    * calls the tool's pre-show method, so the tool can create any
    557      preamble ahead of the message, if it wants.
    558 
    559    * prints the tool-specific parts of the message
    560 
    561    * calls do_actions_on_error.  This optionally does a debugger
    562      attach (and detach), and optionally prints a suppression; both
    563      of these may require user input.
    564 */
    565 static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
    566 {
    567    /* If this fails, you probably specified your tool's method
    568       dictionary incorrectly. */
    569    vg_assert(VG_(needs).tool_errors);
    570 
    571    if (xml) {
    572 
    573       /* Note, allow_db_attach is ignored in here. */
    574 
    575       /* Ensure that suppression generation is either completely
    576          enabled or completely disabled; either way, we won't require
    577          any user input.  m_main.process_cmd_line_options should
    578          ensure the asserted condition holds. */
    579       vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
    580                  || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
    581 
    582       /* Pre-show it to the tool */
    583       VG_TDICT_CALL( tool_before_pp_Error, err );
    584 
    585       /* standard preamble */
    586       VG_(printf_xml)("<error>\n");
    587       VG_(printf_xml)("  <unique>0x%x</unique>\n", err->unique);
    588       VG_(printf_xml)("  <tid>%d</tid>\n", err->tid);
    589 
    590       /* actually print it */
    591       VG_TDICT_CALL( tool_pp_Error, err );
    592 
    593       if (VG_(clo_gen_suppressions) > 0)
    594         gen_suppression(err);
    595 
    596       /* postamble */
    597       VG_(printf_xml)("</error>\n");
    598       VG_(printf_xml)("\n");
    599 
    600    } else {
    601 
    602       VG_TDICT_CALL( tool_before_pp_Error, err );
    603 
    604       if (VG_(tdict).tool_show_ThreadIDs_for_errors
    605           && err->tid > 0 && err->tid != last_tid_printed) {
    606          VG_(umsg)("Thread %d:\n", err->tid );
    607          last_tid_printed = err->tid;
    608       }
    609 
    610       VG_TDICT_CALL( tool_pp_Error, err );
    611       VG_(umsg)("\n");
    612 
    613       do_actions_on_error(err, allow_db_attach);
    614    }
    615 }
    616 
    617 
    618 /* Construct an error */
    619 static
    620 void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
    621                        Char* s, void* extra, ExeContext* where )
    622 {
    623    /* DO NOT MAKE unique_counter NON-STATIC */
    624    static UInt unique_counter = 0;
    625 
    626    tl_assert(tid < VG_N_THREADS);
    627 
    628    /* Core-only parts */
    629    err->unique   = unique_counter++;
    630    err->next     = NULL;
    631    err->supp     = NULL;
    632    err->count    = 1;
    633    err->tid      = tid;
    634    if (NULL == where)
    635      err->where = VG_(record_ExeContext)( tid, 0 );
    636    else
    637       err->where = where;
    638 
    639    /* Tool-relevant parts */
    640    err->ekind  = ekind;
    641    err->addr   = a;
    642    err->extra  = extra;
    643    err->string = s;
    644 
    645    /* sanity... */
    646    vg_assert( tid < VG_N_THREADS );
    647 }
    648 
    649 
    650 
    651 /* Top-level entry point to the error management subsystem.
    652    All detected errors are notified here; this routine decides if/when the
    653    user should see the error. */
    654 void VG_(maybe_record_error) ( ThreadId tid,
    655                                ErrorKind ekind, Addr a, Char* s, void* extra )
    656 {
    657           Error  err;
    658           Error* p;
    659           Error* p_prev;
    660           UInt   extra_size;
    661           VgRes  exe_res          = Vg_MedRes;
    662    static Bool   stopping_message = False;
    663    static Bool   slowdown_message = False;
    664 
    665    /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
    666       been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
    667       have been found, just refuse to collect any more.  This stops
    668       the burden of the error-management system becoming excessive in
    669       extremely buggy programs, although it does make it pretty
    670       pointless to continue the Valgrind run after this point. */
    671    if (VG_(clo_error_limit)
    672        && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
    673            || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
    674        && !VG_(clo_xml)) {
    675       if (!stopping_message) {
    676          VG_(umsg)("\n");
    677 
    678 	 if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
    679             VG_(umsg)(
    680                "More than %d different errors detected.  "
    681                "I'm not reporting any more.\n",
    682                M_COLLECT_NO_ERRORS_AFTER_SHOWN );
    683          } else {
    684             VG_(umsg)(
    685                "More than %d total errors detected.  "
    686                "I'm not reporting any more.\n",
    687                M_COLLECT_NO_ERRORS_AFTER_FOUND );
    688 	 }
    689 
    690          VG_(umsg)("Final error counts will be inaccurate.  "
    691                    "Go fix your program!\n");
    692          VG_(umsg)("Rerun with --error-limit=no to disable "
    693                    "this cutoff.  Note\n");
    694          VG_(umsg)("that errors may occur in your program without "
    695                    "prior warning from\n");
    696          VG_(umsg)("Valgrind, because errors are no longer "
    697                    "being displayed.\n");
    698          VG_(umsg)("\n");
    699          stopping_message = True;
    700       }
    701       return;
    702    }
    703 
    704    /* Ignore it if error acquisition is disabled for this thread. */
    705    { ThreadState* tst = VG_(get_ThreadState)(tid);
    706      if (tst->err_disablement_level > 0)
    707         return;
    708    }
    709 
    710    /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
    711       been found, be much more conservative about collecting new
    712       ones. */
    713    if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
    714        && !VG_(clo_xml)) {
    715       exe_res = Vg_LowRes;
    716       if (!slowdown_message) {
    717          VG_(umsg)("\n");
    718          VG_(umsg)("More than %d errors detected.  Subsequent errors\n",
    719                    M_COLLECT_ERRORS_SLOWLY_AFTER);
    720          VG_(umsg)("will still be recorded, but in less "
    721                    "detail than before.\n");
    722          slowdown_message = True;
    723       }
    724    }
    725 
    726    /* Build ourselves the error */
    727    construct_error ( &err, tid, ekind, a, s, extra, NULL );
    728 
    729    /* First, see if we've got an error record matching this one. */
    730    em_errlist_searches++;
    731    p       = errors;
    732    p_prev  = NULL;
    733    while (p != NULL) {
    734       em_errlist_cmps++;
    735       if (eq_Error(exe_res, p, &err)) {
    736          /* Found it. */
    737          p->count++;
    738 	 if (p->supp != NULL) {
    739             /* Deal correctly with suppressed errors. */
    740             p->supp->count++;
    741             n_errs_suppressed++;
    742          } else {
    743             n_errs_found++;
    744          }
    745 
    746          /* Move p to the front of the list so that future searches
    747             for it are faster. It also allows to print the last
    748             error (see VG_(show_last_error). */
    749          if (p_prev != NULL) {
    750             vg_assert(p_prev->next == p);
    751             p_prev->next = p->next;
    752             p->next      = errors;
    753             errors       = p;
    754 	 }
    755 
    756          return;
    757       }
    758       p_prev = p;
    759       p      = p->next;
    760    }
    761 
    762    /* Didn't see it.  Copy and add. */
    763 
    764    /* OK, we're really going to collect it.  The context is on the stack and
    765       will disappear shortly, so we must copy it.  First do the main
    766       (non-'extra') part.
    767 
    768       Then VG_(tdict).tool_update_extra can update the 'extra' part.  This
    769       is for when there are more details to fill in which take time to work
    770       out but don't affect our earlier decision to include the error -- by
    771       postponing those details until now, we avoid the extra work in the
    772       case where we ignore the error.  Ugly.
    773 
    774       Then, if there is an 'extra' part, copy it too, using the size that
    775       VG_(tdict).tool_update_extra returned.  Also allow for people using
    776       the void* extra field for a scalar value like an integer.
    777    */
    778 
    779    /* copy main part */
    780    p = VG_(arena_malloc)(VG_AR_ERRORS, "errormgr.mre.1", sizeof(Error));
    781    *p = err;
    782 
    783    /* update 'extra' */
    784    switch (ekind) {
    785       //(example code, see comment on CoreSuppKind above)
    786       //case ThreadErr:
    787       //   vg_assert(VG_(needs).core_errors);
    788       //   extra_size = <something>
    789       //   break;
    790       default:
    791          vg_assert(VG_(needs).tool_errors);
    792          extra_size = VG_TDICT_CALL(tool_update_extra, p);
    793          break;
    794    }
    795 
    796    /* copy block pointed to by 'extra', if there is one */
    797    if (NULL != p->extra && 0 != extra_size) {
    798       void* new_extra = VG_(malloc)("errormgr.mre.2", extra_size);
    799       VG_(memcpy)(new_extra, p->extra, extra_size);
    800       p->extra = new_extra;
    801    }
    802 
    803    p->next = errors;
    804    p->supp = is_suppressible_error(&err);
    805    errors  = p;
    806    if (p->supp == NULL) {
    807       /* update stats */
    808       n_err_contexts++;
    809       n_errs_found++;
    810       n_errs_shown++;
    811       /* Actually show the error; more complex than you might think. */
    812       pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
    813    } else {
    814       n_supp_contexts++;
    815       n_errs_suppressed++;
    816       p->supp->count++;
    817    }
    818 }
    819 
    820 /* Second top-level entry point to the error management subsystem, for
    821    errors that the tool wants to report immediately, eg. because they're
    822    guaranteed to only happen once.  This avoids all the recording and
    823    comparing stuff.  But they can be suppressed;  returns True if it is
    824    suppressed.  Bool 'print_error' dictates whether to print the error.
    825    Bool 'count_error' dictates whether to count the error in n_errs_found.
    826 */
    827 Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
    828                          void* extra, ExeContext* where, Bool print_error,
    829                          Bool allow_db_attach, Bool count_error )
    830 {
    831    Error err;
    832    Supp *su;
    833 
    834    /* Ignore it if error acquisition is disabled for this thread. */
    835    ThreadState* tst = VG_(get_ThreadState)(tid);
    836    if (tst->err_disablement_level > 0)
    837       return False; /* ignored, not suppressed */
    838 
    839    /* Build ourselves the error */
    840    construct_error ( &err, tid, ekind, a, s, extra, where );
    841 
    842    /* Unless it's suppressed, we're going to show it.  Don't need to make
    843       a copy, because it's only temporary anyway.
    844 
    845       Then update the 'extra' part with VG_(tdict).tool_update_extra),
    846       because that can have an affect on whether it's suppressed.  Ignore
    847       the size return value of VG_(tdict).tool_update_extra, because we're
    848       not copying 'extra'. */
    849    (void)VG_TDICT_CALL(tool_update_extra, &err);
    850 
    851    su = is_suppressible_error(&err);
    852    if (NULL == su) {
    853       if (count_error) {
    854          n_errs_found++;
    855          n_err_contexts++;
    856       }
    857 
    858       if (print_error) {
    859          /* update stats */
    860          n_errs_shown++;
    861          /* Actually show the error; more complex than you might think. */
    862          pp_Error(&err, allow_db_attach, VG_(clo_xml));
    863       }
    864       return False;
    865 
    866    } else {
    867       if (count_error) {
    868          n_errs_suppressed++;
    869          n_supp_contexts++;
    870       }
    871       su->count++;
    872       return True;
    873    }
    874 }
    875 
    876 
    877 /*------------------------------------------------------------*/
    878 /*--- Exported fns                                         ---*/
    879 /*------------------------------------------------------------*/
    880 
    881 /* Show the used suppressions.  Returns False if no suppression
    882    got used. */
    883 static Bool show_used_suppressions ( void )
    884 {
    885    Supp  *su;
    886    Bool  any_supp;
    887 
    888    if (VG_(clo_xml))
    889       VG_(printf_xml)("<suppcounts>\n");
    890 
    891    any_supp = False;
    892    for (su = suppressions; su != NULL; su = su->next) {
    893       if (su->count <= 0)
    894          continue;
    895       if (VG_(clo_xml)) {
    896          VG_(printf_xml)( "  <pair>\n"
    897                                  "    <count>%d</count>\n"
    898                                  "    <name>%pS</name>\n"
    899                                  "  </pair>\n",
    900                                  su->count, su->sname );
    901       } else {
    902          // blank line before the first shown suppression, if any
    903          if (!any_supp)
    904             VG_(dmsg)("\n");
    905          VG_(dmsg)("used_suppression: %6d %s\n", su->count, su->sname);
    906       }
    907       any_supp = True;
    908    }
    909 
    910    if (VG_(clo_xml))
    911       VG_(printf_xml)("</suppcounts>\n");
    912 
    913    return any_supp;
    914 }
    915 
    916 /* Show all the errors that occurred, and possibly also the
    917    suppressions used. */
    918 void VG_(show_all_errors) (  Int verbosity, Bool xml )
    919 {
    920    Int    i, n_min;
    921    Error *p, *p_min;
    922    Bool   any_supp;
    923 
    924    if (verbosity == 0)
    925       return;
    926 
    927    /* If we're printing XML, just show the suppressions and stop. */
    928    if (xml) {
    929       (void)show_used_suppressions();
    930       return;
    931    }
    932 
    933    /* We only get here if not printing XML. */
    934    VG_(umsg)("ERROR SUMMARY: "
    935              "%d errors from %d contexts (suppressed: %d from %d)\n",
    936              n_errs_found, n_err_contexts,
    937              n_errs_suppressed, n_supp_contexts );
    938 
    939    if (verbosity <= 1)
    940       return;
    941 
    942    // We do the following only at -v or above, and only in non-XML
    943    // mode
    944 
    945    /* Print the contexts in order of increasing error count.
    946       Once an error is shown, we add a huge value to its count to filter it
    947       out. After having shown all errors, we reset count to the original value. */
    948    for (i = 0; i < n_err_contexts; i++) {
    949       n_min = (1 << 30) - 1;
    950       p_min = NULL;
    951       for (p = errors; p != NULL; p = p->next) {
    952          if (p->supp != NULL) continue;
    953          if (p->count < n_min) {
    954             n_min = p->count;
    955             p_min = p;
    956          }
    957       }
    958       // XXX: this isn't right.  See bug 203651.
    959       if (p_min == NULL) continue; //VG_(tool_panic)("show_all_errors()");
    960 
    961       VG_(umsg)("\n");
    962       VG_(umsg)("%d errors in context %d of %d:\n",
    963                 p_min->count, i+1, n_err_contexts);
    964       pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );
    965 
    966       // We're not printing XML -- we'd have exited above if so.
    967       vg_assert(! xml);
    968 
    969       if ((i+1 == VG_(clo_dump_error))) {
    970          StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
    971          VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
    972                           ips[0], /*debugging*/True, 0xFE/*verbosity*/,
    973                           /*bbs_done*/0,
    974                           /*allow redir?*/True);
    975       }
    976 
    977       p_min->count = p_min->count + (1 << 30);
    978    }
    979 
    980    /* reset the counts, otherwise a 2nd call does not show anything anymore */
    981    for (p = errors; p != NULL; p = p->next) {
    982       if (p->count >= (1 << 30))
    983          p->count = p->count - (1 << 30);
    984    }
    985 
    986 
    987    any_supp = show_used_suppressions();
    988 
    989    if (any_supp)
    990       VG_(umsg)("\n");
    991    // reprint this, so users don't have to scroll way up to find
    992    // the first printing
    993    VG_(umsg)("ERROR SUMMARY: "
    994              "%d errors from %d contexts (suppressed: %d from %d)\n",
    995              n_errs_found, n_err_contexts, n_errs_suppressed,
    996              n_supp_contexts );
    997 }
    998 
    999 void VG_(show_last_error) ( void )
   1000 {
   1001    if (n_err_contexts == 0) {
   1002       VG_(umsg)("No errors yet\n");
   1003       return;
   1004    }
   1005 
   1006    pp_Error( errors, False/*allow_db_attach*/, False/*xml*/ );
   1007 }
   1008 
   1009 
   1010 /* Show occurrence counts of all errors, in XML form. */
   1011 void VG_(show_error_counts_as_XML) ( void )
   1012 {
   1013    Error* err;
   1014    VG_(printf_xml)("<errorcounts>\n");
   1015    for (err = errors; err != NULL; err = err->next) {
   1016       if (err->supp != NULL)
   1017          continue;
   1018       if (err->count <= 0)
   1019          continue;
   1020       VG_(printf_xml)("  <pair>\n");
   1021       VG_(printf_xml)("    <count>%d</count>\n", err->count);
   1022       VG_(printf_xml)("    <unique>0x%x</unique>\n", err->unique);
   1023       VG_(printf_xml)("  </pair>\n");
   1024    }
   1025    VG_(printf_xml)("</errorcounts>\n");
   1026    VG_(printf_xml)("\n");
   1027 }
   1028 
   1029 
   1030 /*------------------------------------------------------------*/
   1031 /*--- Suppression parsing                                  ---*/
   1032 /*------------------------------------------------------------*/
   1033 
   1034 /* Get the next char from fd into *out_buf.  Returns 1 if success,
   1035    0 if eof or < 0 if error. */
   1036 
   1037 static Int get_char ( Int fd, Char* out_buf )
   1038 {
   1039    Int r;
   1040    static Char buf[256];
   1041    static Int buf_size = 0;
   1042    static Int buf_used = 0;
   1043    vg_assert(buf_size >= 0 && buf_size <= 256);
   1044    vg_assert(buf_used >= 0 && buf_used <= buf_size);
   1045    if (buf_used == buf_size) {
   1046       r = VG_(read)(fd, buf, 256);
   1047       if (r < 0) return r; /* read failed */
   1048       vg_assert(r >= 0 && r <= 256);
   1049       buf_size = r;
   1050       buf_used = 0;
   1051    }
   1052    if (buf_size == 0)
   1053      return 0; /* eof */
   1054    vg_assert(buf_size >= 0 && buf_size <= 256);
   1055    vg_assert(buf_used >= 0 && buf_used < buf_size);
   1056    *out_buf = buf[buf_used];
   1057    buf_used++;
   1058    return 1;
   1059 }
   1060 
   1061 Bool VG_(get_line) ( Int fd, Char** bufpp, SizeT* nBufp, Int* lineno )
   1062 {
   1063    Char* buf  = *bufpp;
   1064    SizeT nBuf = *nBufp;
   1065    Char  ch;
   1066    Int   n, i;
   1067    while (True) {
   1068       /* First, read until a non-blank char appears. */
   1069       while (True) {
   1070          n = get_char(fd, &ch);
   1071          if (n == 1 && !VG_(isspace)(ch)) break;
   1072          if (n == 1 && ch == '\n' && lineno)
   1073             (*lineno)++;
   1074          if (n <= 0) return True;
   1075       }
   1076 
   1077       /* Now, read the line into buf. */
   1078       i = 0;
   1079       buf[i++] = ch; buf[i] = 0;
   1080       while (True) {
   1081          n = get_char(fd, &ch);
   1082          if (n <= 0) return False; /* the next call will return True */
   1083          if (ch == '\n' && lineno)
   1084             (*lineno)++;
   1085          if (ch == '\n') break;
   1086          if (i > 0 && i == nBuf-1) {
   1087             *nBufp = nBuf = nBuf * 2;
   1088             #define RIDICULOUS   100000
   1089             vg_assert2(nBuf < RIDICULOUS,  // Just a sanity check, really.
   1090                "VG_(get_line): line longer than %d chars, aborting\n",
   1091                RIDICULOUS);
   1092             *bufpp = buf = VG_(realloc)("errormgr.get_line.1", buf, nBuf);
   1093          }
   1094          buf[i++] = ch; buf[i] = 0;
   1095       }
   1096       while (i > 1 && VG_(isspace)(buf[i-1])) {
   1097          i--; buf[i] = 0;
   1098       };
   1099 
   1100       /* VG_(printf)("The line is '%s'\n", buf); */
   1101       /* Ok, we have a line.  If a non-comment line, return.
   1102          If a comment line, start all over again. */
   1103       if (buf[0] != '#') return False;
   1104    }
   1105 }
   1106 
   1107 
   1108 /* True if s contains no wildcard (?, *) characters. */
   1109 static Bool is_simple_str (Char *s)
   1110 {
   1111    while (*s) {
   1112       if (*s == '?' || *s == '*')
   1113          return False;
   1114       s++;
   1115    }
   1116    return True;
   1117 }
   1118 
   1119 /* buf contains the raw name of a caller, supposedly either
   1120        fun:some_function_name   or
   1121        obj:some_object_name     or
   1122        ...
   1123    Set p->ty and p->name accordingly.
   1124    p->name is allocated and set to the string
   1125    after the descriptor (fun: or obj:) part.
   1126    Returns False if failed.
   1127 */
   1128 static Bool setLocationTy ( SuppLoc* p, Char *buf )
   1129 {
   1130    if (VG_(strncmp)(buf, "fun:", 4) == 0) {
   1131       p->name = VG_(arena_strdup)(VG_AR_CORE,
   1132                                   "errormgr.sLTy.1", buf+4);
   1133       p->name_is_simple_str = is_simple_str (p->name);
   1134       p->ty = FunName;
   1135       return True;
   1136    }
   1137    if (VG_(strncmp)(buf, "obj:", 4) == 0) {
   1138       p->name = VG_(arena_strdup)(VG_AR_CORE,
   1139                                   "errormgr.sLTy.2", buf+4);
   1140       p->name_is_simple_str = is_simple_str (p->name);
   1141       p->ty = ObjName;
   1142       return True;
   1143    }
   1144    if (VG_(strcmp)(buf, "...") == 0) {
   1145       p->name = NULL;
   1146       p->name_is_simple_str = False;
   1147       p->ty = DotDotDot;
   1148       return True;
   1149    }
   1150    VG_(printf)("location should be \"...\", or should start "
   1151                "with \"fun:\" or \"obj:\"\n");
   1152    return False;
   1153 }
   1154 
   1155 
   1156 /* Look for "tool" in a string like "tool1,tool2,tool3" */
   1157 static Bool tool_name_present(Char *name, Char *names)
   1158 {
   1159    Bool  found;
   1160    Char *s = NULL;   /* Shut gcc up */
   1161    Int   len = VG_(strlen)(name);
   1162 
   1163    found = (NULL != (s = VG_(strstr)(names, name)) &&
   1164             (s        == names || *(s-1)   == ',') &&
   1165             (*(s+len) == ','   || *(s+len) == '\0')
   1166            );
   1167 
   1168    return found;
   1169 }
   1170 
   1171 /* Read suppressions from the file specified in VG_(clo_suppressions)
   1172    and place them in the suppressions list.  If there's any difficulty
   1173    doing this, just give up -- there's no point in trying to recover.
   1174 */
   1175 static void load_one_suppressions_file ( Char* filename )
   1176 {
   1177    SysRes sres;
   1178    Int    fd, i, j, lineno = 0;
   1179    Bool   eof;
   1180    SizeT  nBuf = 200;
   1181    Char*  buf = VG_(malloc)("errormgr.losf.1", nBuf);
   1182    Char*  tool_names;
   1183    Char*  supp_name;
   1184    Char*  err_str = NULL;
   1185    SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
   1186 
   1187    // Check it's not a directory.
   1188    if (VG_(is_dir)( filename )) {
   1189       if (VG_(clo_xml))
   1190          VG_(printf_xml)("</valgrindoutput>\n");
   1191       VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
   1192       VG_(exit)(1);
   1193    }
   1194 
   1195    // Open the suppression file.
   1196    sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
   1197    if (sr_isError(sres)) {
   1198       if (VG_(clo_xml))
   1199          VG_(printf_xml)("</valgrindoutput>\n");
   1200       VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
   1201       VG_(exit)(1);
   1202    }
   1203    fd = sr_Res(sres);
   1204 
   1205 #  define BOMB(S)  { err_str = S;  goto syntax_error; }
   1206 
   1207    while (True) {
   1208       /* Assign and initialise the two suppression halves (core and tool) */
   1209       Supp* supp;
   1210       supp        = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.1",
   1211                                       sizeof(Supp));
   1212       supp->count = 0;
   1213 
   1214       // Initialise temporary reading-in buffer.
   1215       for (i = 0; i < VG_MAX_SUPP_CALLERS; i++) {
   1216          tmp_callers[i].ty   = NoName;
   1217          tmp_callers[i].name_is_simple_str = False;
   1218          tmp_callers[i].name = NULL;
   1219       }
   1220 
   1221       supp->string = supp->extra = NULL;
   1222 
   1223       eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1224       if (eof) {
   1225          VG_(arena_free)(VG_AR_CORE, supp);
   1226          break;
   1227       }
   1228 
   1229       if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
   1230 
   1231       eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1232 
   1233       if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
   1234 
   1235       supp->sname = VG_(arena_strdup)(VG_AR_CORE, "errormgr.losf.2", buf);
   1236 
   1237       eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1238 
   1239       if (eof) BOMB("unexpected end-of-file");
   1240 
   1241       /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
   1242       i = 0;
   1243       while (True) {
   1244          if (buf[i] == ':')  break;
   1245          if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
   1246          i++;
   1247       }
   1248       buf[i]    = '\0';    /* Replace ':', splitting into two strings */
   1249 
   1250       tool_names = & buf[0];
   1251       supp_name  = & buf[i+1];
   1252 
   1253       if (VG_(needs).core_errors && tool_name_present("core", tool_names))
   1254       {
   1255          // A core suppression
   1256          //(example code, see comment on CoreSuppKind above)
   1257          //if (VG_STREQ(supp_name, "Thread"))
   1258          //   supp->skind = ThreadSupp;
   1259          //else
   1260             BOMB("unknown core suppression type");
   1261       }
   1262       else if (VG_(needs).tool_errors &&
   1263                tool_name_present(VG_(details).name, tool_names))
   1264       {
   1265          // A tool suppression
   1266          if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
   1267             /* Do nothing, function fills in supp->skind */
   1268          } else {
   1269             BOMB("unknown tool suppression type");
   1270          }
   1271       }
   1272       else {
   1273          // Ignore rest of suppression
   1274          while (True) {
   1275             eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1276             if (eof) BOMB("unexpected end-of-file");
   1277             if (VG_STREQ(buf, "}"))
   1278                break;
   1279          }
   1280          VG_(arena_free)(VG_AR_CORE, supp->sname);
   1281          VG_(arena_free)(VG_AR_CORE, supp);
   1282          continue;
   1283       }
   1284 
   1285       if (VG_(needs).tool_errors &&
   1286           !VG_TDICT_CALL(tool_read_extra_suppression_info,
   1287                          fd, &buf, &nBuf, supp))
   1288       {
   1289          BOMB("bad or missing extra suppression info");
   1290       }
   1291 
   1292       /* the main frame-descriptor reading loop */
   1293       i = 0;
   1294       while (True) {
   1295          eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1296          if (eof)
   1297             BOMB("unexpected end-of-file");
   1298          if (VG_STREQ(buf, "}")) {
   1299             if (i > 0) {
   1300                break;
   1301             } else {
   1302                BOMB("missing stack trace");
   1303             }
   1304          }
   1305          if (i == VG_MAX_SUPP_CALLERS)
   1306             BOMB("too many callers in stack trace");
   1307          if (i > 0 && i >= VG_(clo_backtrace_size))
   1308             break;
   1309          if (!setLocationTy(&(tmp_callers[i]), buf))
   1310             BOMB("location should be \"...\", or should start "
   1311                  "with \"fun:\" or \"obj:\"");
   1312          i++;
   1313       }
   1314 
   1315       // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
   1316       // lines and grab the '}'.
   1317       if (!VG_STREQ(buf, "}")) {
   1318          do {
   1319             eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
   1320          } while (!eof && !VG_STREQ(buf, "}"));
   1321       }
   1322 
   1323       // Reject entries which are entirely composed of frame
   1324       // level wildcards.
   1325       vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
   1326       for (j = 0; j < i; j++) {
   1327          if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
   1328             break;
   1329          vg_assert(tmp_callers[j].ty == DotDotDot);
   1330       }
   1331       vg_assert(j >= 0 && j <= i);
   1332       if (j == i) {
   1333          // we didn't find any non-"..." entries
   1334          BOMB("suppression must contain at least one location "
   1335               "line which is not \"...\"");
   1336       }
   1337 
   1338       // Copy tmp_callers[] into supp->callers[]
   1339       supp->n_callers = i;
   1340       supp->callers = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.4",
   1341                                         i*sizeof(SuppLoc));
   1342       for (i = 0; i < supp->n_callers; i++) {
   1343          supp->callers[i] = tmp_callers[i];
   1344       }
   1345 
   1346       supp->next = suppressions;
   1347       suppressions = supp;
   1348    }
   1349    VG_(free)(buf);
   1350    VG_(close)(fd);
   1351    return;
   1352 
   1353   syntax_error:
   1354    if (VG_(clo_xml))
   1355       VG_(printf_xml)("</valgrindoutput>\n");
   1356    VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
   1357            filename, lineno );
   1358    VG_(umsg)("   %s\n", err_str );
   1359 
   1360    VG_(close)(fd);
   1361    VG_(umsg)("exiting now.\n");
   1362    VG_(exit)(1);
   1363 
   1364 #  undef BOMB
   1365 }
   1366 
   1367 
   1368 void VG_(load_suppressions) ( void )
   1369 {
   1370    Int i;
   1371    suppressions = NULL;
   1372    for (i = 0; i < VG_(clo_n_suppressions); i++) {
   1373       if (VG_(clo_verbosity) > 1) {
   1374          VG_(dmsg)("Reading suppressions file: %s\n",
   1375                    VG_(clo_suppressions)[i] );
   1376       }
   1377       load_one_suppressions_file( VG_(clo_suppressions)[i] );
   1378    }
   1379 }
   1380 
   1381 
   1382 /*------------------------------------------------------------*/
   1383 /*--- Matching errors to suppressions                      ---*/
   1384 /*------------------------------------------------------------*/
   1385 
   1386 /* Parameterising functions for the use of VG_(generic_match) in
   1387    suppression-vs-error matching.  The suppression frames (SuppLoc)
   1388    play the role of 'pattern'-element, and the error frames (IPs,
   1389    hence simply Addrs) play the role of 'input'.  In short then, we're
   1390    matching a sequence of Addrs against a pattern composed of a
   1391    sequence of SuppLocs.
   1392 */
   1393 static Bool supploc_IsStar ( void* supplocV )
   1394 {
   1395    SuppLoc* supploc = (SuppLoc*)supplocV;
   1396    return supploc->ty == DotDotDot;
   1397 }
   1398 
   1399 static Bool supploc_IsQuery ( void* supplocV )
   1400 {
   1401    return False; /* there's no '?' equivalent in the supp syntax */
   1402 }
   1403 
   1404 /* IPtoFunOrObjCompleter is a lazy completer of the IPs
   1405    needed to match an error with the suppression patterns.
   1406    The matching between an IP and a suppression pattern is done either
   1407    with the IP function name or with the IP object name.
   1408    First time the fun or obj name is needed for an IP member
   1409    of a stack trace, it will be computed and stored in names.
   1410    The IPtoFunOrObjCompleter type is designed to minimise the nr of
   1411    allocations and the nr of debuginfo search. */
   1412 typedef
   1413    struct {
   1414       StackTrace ips; // stack trace we are lazily completing.
   1415       UWord n_ips; // nr of elements in ips.
   1416 
   1417       Int* fun_offsets;
   1418       // fun_offsets[i] is the offset in names where the
   1419       // function name for ips[i] is located.
   1420       // An offset -1 means the function name is not yet completed.
   1421       Int* obj_offsets;
   1422       // Similarly, obj_offsets[i] gives the offset for the
   1423       // object name for ips[i] (-1 meaning object name not yet completed).
   1424 
   1425       // All function names and object names will be concatenated
   1426       // in names. names is reallocated on demand.
   1427       Char *names;
   1428       Int   names_szB;  // size of names.
   1429       Int   names_free; // offset first free Char in names.
   1430    }
   1431    IPtoFunOrObjCompleter;
   1432 
   1433 // free the memory in ip2fo.
   1434 static void clearIPtoFunOrObjCompleter
   1435   (IPtoFunOrObjCompleter* ip2fo)
   1436 {
   1437    if (ip2fo->fun_offsets) VG_(free)(ip2fo->fun_offsets);
   1438    if (ip2fo->obj_offsets) VG_(free)(ip2fo->obj_offsets);
   1439    if (ip2fo->names)       VG_(free)(ip2fo->names);
   1440 }
   1441 
   1442 /* foComplete returns the function name or object name for IP.
   1443    If needFun, returns the function name for IP
   1444    else returns the object name for IP.
   1445    The function name or object name will be computed and added in
   1446    names if not yet done.
   1447    IP must be equal to focompl->ipc[ixIP]. */
   1448 static Char* foComplete(IPtoFunOrObjCompleter* ip2fo,
   1449                         Addr IP, Int ixIP, Bool needFun)
   1450 {
   1451    vg_assert (ixIP < ip2fo->n_ips);
   1452    vg_assert (IP == ip2fo->ips[ixIP]);
   1453 
   1454    // ptr to the offset array for function offsets (if needFun)
   1455    // or object offsets (if !needFun).
   1456    Int** offsets;
   1457    if (needFun)
   1458       offsets = &ip2fo->fun_offsets;
   1459    else
   1460       offsets = &ip2fo->obj_offsets;
   1461 
   1462    // Allocate offsets if not yet done.
   1463    if (!*offsets) {
   1464       Int i;
   1465       *offsets =
   1466          VG_(malloc)("foComplete",
   1467                      ip2fo->n_ips * sizeof(Int));
   1468       for (i = 0; i < ip2fo->n_ips; i++)
   1469          (*offsets)[i] = -1;
   1470    }
   1471 
   1472    // Complete Fun name or Obj name for IP if not yet done.
   1473    if ((*offsets)[ixIP] == -1) {
   1474       /* Ensure we have ERRTXT_LEN characters available in names */
   1475       if (ip2fo->names_szB
   1476             < ip2fo->names_free + ERRTXT_LEN) {
   1477          ip2fo->names
   1478             = VG_(realloc)("foc_names",
   1479                            ip2fo->names,
   1480                            ip2fo->names_szB + ERRTXT_LEN);
   1481          ip2fo->names_szB += ERRTXT_LEN;
   1482       }
   1483       Char* caller_name = ip2fo->names + ip2fo->names_free;
   1484       (*offsets)[ixIP] = ip2fo->names_free;
   1485       if (needFun) {
   1486          /* Get the function name into 'caller_name', or "???"
   1487             if unknown. */
   1488          // Nb: C++-mangled names are used in suppressions.  Do, though,
   1489          // Z-demangle them, since otherwise it's possible to wind
   1490          // up comparing "malloc" in the suppression against
   1491          // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
   1492          // two of them need to be made to match.
   1493          if (!VG_(get_fnname_no_cxx_demangle)(IP, caller_name, ERRTXT_LEN))
   1494             VG_(strcpy)(caller_name, "???");
   1495       } else {
   1496          /* Get the object name into 'caller_name', or "???"
   1497             if unknown. */
   1498          if (!VG_(get_objname)(IP, caller_name, ERRTXT_LEN))
   1499             VG_(strcpy)(caller_name, "???");
   1500       }
   1501       ip2fo->names_free += VG_(strlen)(caller_name) + 1;
   1502    }
   1503 
   1504    return ip2fo->names + (*offsets)[ixIP];
   1505 }
   1506 
   1507 static Bool supp_pattEQinp ( void* supplocV, void* addrV,
   1508                              void* inputCompleter, UWord ixAddrV )
   1509 {
   1510    SuppLoc* supploc = (SuppLoc*)supplocV; /* PATTERN */
   1511    Addr     ip      = *(Addr*)addrV; /* INPUT */
   1512    IPtoFunOrObjCompleter* ip2fo
   1513       = (IPtoFunOrObjCompleter*)inputCompleter;
   1514    Char* funobj_name; // Fun or Obj name.
   1515 
   1516    /* So, does this IP address match this suppression-line? */
   1517    switch (supploc->ty) {
   1518       case DotDotDot:
   1519          /* supp_pattEQinp is a callback from VG_(generic_match).  As
   1520             per the spec thereof (see include/pub_tool_seqmatch.h), we
   1521             should never get called with a pattern value for which the
   1522             _IsStar or _IsQuery function would return True.  Hence
   1523             this can't happen. */
   1524          vg_assert(0);
   1525       case ObjName:
   1526          funobj_name = foComplete(ip2fo, ip, ixAddrV, False /*needFun*/);
   1527          break;
   1528       case FunName:
   1529          funobj_name = foComplete(ip2fo, ip, ixAddrV, True /*needFun*/);
   1530          break;
   1531       default:
   1532         vg_assert(0);
   1533    }
   1534 
   1535    /* So now we have the function or object name in funobj_name, and
   1536       the pattern (at the character level) to match against is in
   1537       supploc->name.  Hence (and leading to a re-entrant call of
   1538       VG_(generic_match) if there is a wildcard character): */
   1539    if (supploc->name_is_simple_str)
   1540       return VG_(strcmp) (supploc->name, funobj_name) == 0;
   1541    else
   1542       return VG_(string_match)(supploc->name, funobj_name);
   1543 }
   1544 
   1545 /////////////////////////////////////////////////////
   1546 
   1547 static Bool supp_matches_callers(IPtoFunOrObjCompleter* ip2fo, Supp* su)
   1548 {
   1549    /* Unwrap the args and set up the correct parameterisation of
   1550       VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
   1551       supp_pattEQinp. */
   1552    /* note, StackTrace ip2fo->ips === Addr* */
   1553    SuppLoc*   supps    = su->callers;
   1554    UWord      n_supps  = su->n_callers;
   1555    UWord      szbPatt  = sizeof(SuppLoc);
   1556    UWord      szbInput = sizeof(Addr);
   1557    Bool       matchAll = False; /* we just want to match a prefix */
   1558    return
   1559       VG_(generic_match)(
   1560          matchAll,
   1561          /*PATT*/supps, szbPatt, n_supps, 0/*initial Ix*/,
   1562          /*INPUT*/ip2fo->ips, szbInput, ip2fo->n_ips,  0/*initial Ix*/,
   1563          supploc_IsStar, supploc_IsQuery, supp_pattEQinp,
   1564          ip2fo
   1565       );
   1566 }
   1567 
   1568 /////////////////////////////////////////////////////
   1569 
   1570 static
   1571 Bool supp_matches_error(Supp* su, Error* err)
   1572 {
   1573    switch (su->skind) {
   1574       //(example code, see comment on CoreSuppKind above)
   1575       //case ThreadSupp:
   1576       //   return (err->ekind == ThreadErr);
   1577       default:
   1578          if (VG_(needs).tool_errors) {
   1579             return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
   1580          } else {
   1581             VG_(printf)(
   1582                "\nUnhandled suppression type: %u.  VG_(needs).tool_errors\n"
   1583                "probably needs to be set.\n",
   1584                err->ekind);
   1585             VG_(tool_panic)("unhandled suppression type");
   1586          }
   1587    }
   1588 }
   1589 
   1590 /////////////////////////////////////////////////////
   1591 
   1592 /* Does an error context match a suppression?  ie is this a suppressible
   1593    error?  If so, return a pointer to the Supp record, otherwise NULL.
   1594    Tries to minimise the number of symbol searches since they are expensive.
   1595 */
   1596 static Supp* is_suppressible_error ( Error* err )
   1597 {
   1598    Supp* su;
   1599    Supp* su_prev;
   1600 
   1601    IPtoFunOrObjCompleter ip2fo;
   1602    /* Conceptually, ip2fo contains an array of function names and an array of
   1603       object names, corresponding to the array of IP of err->where.
   1604       These names are just computed 'on demand' (so once maximum),
   1605       then stored (efficiently, avoiding too many allocs) in ip2fo to be re-usable
   1606       for the matching of the same IP with the next suppression pattern.
   1607 
   1608       VG_(generic_match) gets this 'IP to Fun or Obj name completer' as one
   1609       of its arguments. It will then pass it to the function
   1610       supp_pattEQinp which will then lazily complete the IP function name or
   1611       object name inside ip2fo. Next time the fun or obj name for the same
   1612       IP is needed (i.e. for the matching with the next suppr pattern), then
   1613       the fun or obj name will not be searched again in the debug info. */
   1614 
   1615    /* stats gathering */
   1616    em_supplist_searches++;
   1617 
   1618    /* Prepare the lazy input completer. */
   1619    ip2fo.ips = VG_(get_ExeContext_StackTrace)(err->where);
   1620    ip2fo.n_ips = VG_(get_ExeContext_n_ips)(err->where);
   1621    ip2fo.fun_offsets = NULL;
   1622    ip2fo.obj_offsets = NULL;
   1623    ip2fo.names = NULL;
   1624    ip2fo.names_szB = 0;
   1625    ip2fo.names_free = 0;
   1626 
   1627    /* See if the error context matches any suppression. */
   1628    su_prev = NULL;
   1629    for (su = suppressions; su != NULL; su = su->next) {
   1630       em_supplist_cmps++;
   1631       if (supp_matches_error(su, err)
   1632           && supp_matches_callers(&ip2fo, su)) {
   1633          /* got a match.  Move this entry to the head of the list
   1634             in the hope of making future searches cheaper. */
   1635          if (su_prev) {
   1636             vg_assert(su_prev->next == su);
   1637             su_prev->next = su->next;
   1638             su->next = suppressions;
   1639             suppressions = su;
   1640          }
   1641          clearIPtoFunOrObjCompleter(&ip2fo);
   1642          return su;
   1643       }
   1644       su_prev = su;
   1645    }
   1646    clearIPtoFunOrObjCompleter(&ip2fo);
   1647    return NULL;      /* no matches */
   1648 }
   1649 
   1650 /* Show accumulated error-list and suppression-list search stats.
   1651 */
   1652 void VG_(print_errormgr_stats) ( void )
   1653 {
   1654    VG_(dmsg)(
   1655       " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
   1656       em_supplist_searches, em_supplist_cmps
   1657    );
   1658    VG_(dmsg)(
   1659       " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
   1660       em_errlist_searches, em_errlist_cmps
   1661    );
   1662 }
   1663 
   1664 /*--------------------------------------------------------------------*/
   1665 /*--- end                                                          ---*/
   1666 /*--------------------------------------------------------------------*/
   1667