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@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. */
74static 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(). */
79static Supp* suppressions = NULL;
80
81/* Running count of unsuppressed errors detected. */
82static UInt n_errs_found = 0;
83
84/* Running count of suppressed errors detected. */
85static UInt n_errs_suppressed = 0;
86
87/* Running count of errors shown. */
88static UInt n_errs_shown = 0;
89
90/* Running count of unsuppressed error contexts. */
91static UInt n_err_contexts = 0;
92
93/* Running count of suppressed error contexts. */
94static UInt n_supp_contexts = 0;
95
96
97/* forwards ... */
98static Supp* is_suppressible_error ( const Error* err );
99
100static ThreadId last_tid_printed = 1;
101
102/* Stats: number of searches of the error list initiated. */
103static UWord em_errlist_searches = 0;
104
105/* Stats: number of comparisons done during error list
106   searching. */
107static UWord em_errlist_cmps = 0;
108
109/* Stats: number of searches of the suppression list initiated. */
110static UWord em_supplist_searches = 0;
111
112/* Stats: number of comparisons done during suppression list
113   searching. */
114static 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*/
129struct _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
149ExeContext* VG_(get_error_where) ( const Error* err )
150{
151   return err->where;
152}
153
154ErrorKind VG_(get_error_kind) ( const Error* err )
155{
156   return err->ekind;
157}
158
159Addr VG_(get_error_address) ( const Error* err )
160{
161   return err->addr;
162}
163
164const HChar* VG_(get_error_string) ( const Error* err )
165{
166   return err->string;
167}
168
169void* VG_(get_error_extra)  ( const Error* err )
170{
171   return err->extra;
172}
173
174UInt VG_(get_n_errs_found)( void )
175{
176   return n_errs_found;
177}
178
179UInt 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. */
190typedef
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. */
204typedef
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
213typedef
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'. */
226struct _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
248SuppKind VG_(get_supp_kind) ( const Supp* su )
249{
250   return su->skind;
251}
252
253HChar* VG_(get_supp_string) ( const Supp* su )
254{
255   return su->string;
256}
257
258void* VG_(get_supp_extra)  ( const Supp* su )
259{
260   return su->extra;
261}
262
263
264void VG_(set_supp_kind)   ( Supp* su, SuppKind skind )
265{
266   su->skind = skind;
267}
268
269void VG_(set_supp_string) ( Supp* su, HChar* string )
270{
271   su->string = string;
272}
273
274void 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.
286Bool 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*/
293static 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
325static 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
342static 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*/
362static 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*/
470Bool 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*/
522static
523void 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*/
583static 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 */
649static
650void 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. */
684void 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*/
866Bool 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. */
922static 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. */
977void 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
1059void 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. */
1071void 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
1097static 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.
1123static 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 ...
1174static 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
1181Bool 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. */
1195static 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*/
1214static 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" */
1241static 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*/
1260static 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
1466void 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*/
1491static Bool supploc_IsStar ( const void* supplocV )
1492{
1493   const SuppLoc* supploc = supplocV;
1494   return supploc->ty == DotDotDot;
1495}
1496
1497static 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. */
1512typedef
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
1570static 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. */
1598static 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. */
1622static 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. */
1642static 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.
1720static 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.
1756static 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
1802static Bool haveInputInpC (void* inputCompleter, UWord ixInput )
1803{
1804   IPtoFunOrObjCompleter* ip2fo = inputCompleter;
1805   expandInput(ip2fo, ixInput);
1806   return ixInput < ip2fo->n_expanded;
1807}
1808
1809static 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
1857static 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
1890static
1891Bool 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*/
1916static 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*/
1982void 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