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