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