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