
/*--------------------------------------------------------------------*/
/*--- Management of error messages.                   m_errormgr.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2000-2013 Julian Seward 
      jseward@acm.org

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

#include "pub_core_basics.h"
#include "pub_core_vki.h"
#include "pub_core_libcsetjmp.h"
#include "pub_core_threadstate.h"      // For VG_N_THREADS
#include "pub_core_debugger.h"
#include "pub_core_debuginfo.h"
#include "pub_core_errormgr.h"
#include "pub_core_execontext.h"
#include "pub_core_gdbserver.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcfile.h"
#include "pub_core_libcprint.h"
#include "pub_core_libcproc.h"         // For VG_(getpid)()
#include "pub_core_seqmatch.h"
#include "pub_core_mallocfree.h"
#include "pub_core_options.h"
#include "pub_core_stacktrace.h"
#include "pub_core_tooliface.h"
#include "pub_core_translate.h"        // for VG_(translate)()
#include "pub_core_xarray.h"           // VG_(xaprintf) et al

/*------------------------------------------------------------*/
/*--- Globals                                              ---*/
/*------------------------------------------------------------*/

/* After this many different unsuppressed errors have been observed,
   be more conservative about collecting new ones. */
#define M_COLLECT_ERRORS_SLOWLY_AFTER 100

/* After this many different unsuppressed errors have been observed,
   stop collecting errors at all, and tell the user their program is
   evidently a steaming pile of camel dung. */
#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000

/* After this many total errors have been observed, stop collecting
   errors at all.  Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
#define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000

/* The list of error contexts found, both suppressed and unsuppressed.
   Initially empty, and grows as errors are detected. */
static Error* errors = NULL;

/* The list of suppression directives, as read from the specified
   suppressions file.  Note that the list gets rearranged as a result
   of the searches done by is_suppressible_error(). */
static Supp* suppressions = NULL;

/* Running count of unsuppressed errors detected. */
static UInt n_errs_found = 0;

/* Running count of suppressed errors detected. */
static UInt n_errs_suppressed = 0;

/* Running count of errors shown. */
static UInt n_errs_shown = 0;

/* Running count of unsuppressed error contexts. */
static UInt n_err_contexts = 0;

/* Running count of suppressed error contexts. */
static UInt n_supp_contexts = 0;


/* forwards ... */
static Supp* is_suppressible_error ( Error* err );

static ThreadId last_tid_printed = 1;

/* Stats: number of searches of the error list initiated. */
static UWord em_errlist_searches = 0;

/* Stats: number of comparisons done during error list
   searching. */
static UWord em_errlist_cmps = 0;

/* Stats: number of searches of the suppression list initiated. */
static UWord em_supplist_searches = 0;

/* Stats: number of comparisons done during suppression list
   searching. */
static UWord em_supplist_cmps = 0;

/*------------------------------------------------------------*/
/*--- Error type                                           ---*/
/*------------------------------------------------------------*/

/* Errors.  Extensible (via the 'extra' field).  Tools can use a normal
   enum (with element values in the normal range (0..)) for 'ekind'. 
   Functions for getting/setting the tool-relevant fields are in
   include/pub_tool_errormgr.h.

   When errors are found and recorded with VG_(maybe_record_error)(), all
   the tool must do is pass in the four parameters;  core will
   allocate/initialise the error record.
*/
struct _Error {
   struct _Error* next;
   // Unique tag.  This gives the error a unique identity (handle) by
   // which it can be referred to afterwords.  Currently only used for
   // XML printing.
   UInt unique;
   // NULL if unsuppressed; or ptr to suppression record.
   Supp* supp;
   Int count;

   // The tool-specific part
   ThreadId tid;           // Initialised by core
   ExeContext* where;      // Initialised by core
   ErrorKind ekind;        // Used by ALL.  Must be in the range (0..)
   Addr addr;              // Used frequently
   const HChar* string;    // Used frequently
   void* extra;            // For any tool-specific extras
};


ExeContext* VG_(get_error_where) ( Error* err )
{
   return err->where;
}

ErrorKind VG_(get_error_kind) ( Error* err )
{
   return err->ekind;
}

Addr VG_(get_error_address) ( Error* err )
{
   return err->addr;
}

const HChar* VG_(get_error_string) ( Error* err )
{
   return err->string;
}

void* VG_(get_error_extra)  ( Error* err )
{
   return err->extra;
}

UInt VG_(get_n_errs_found)( void )
{
   return n_errs_found;
}

UInt VG_(get_n_errs_shown)( void )
{
   return n_errs_shown;
}

/*------------------------------------------------------------*/
/*--- Suppression type                                     ---*/
/*------------------------------------------------------------*/

/* Note: it is imperative this doesn't overlap with (0..) at all, as tools
 * effectively extend it by defining their own enums in the (0..) range. */
typedef
   enum {
      // Nb: thread errors are a relic of the time when Valgrind's core
      // could detect them.  This example is left commented-out as an
      // example should new core errors ever be added.
      ThreadSupp = -1,    /* Matches ThreadErr */
   }
   CoreSuppKind;

/* Max number of callers for context in a suppression. */
#define VG_MAX_SUPP_CALLERS  24

/* For each caller specified for a suppression, record the nature of
   the caller name.  Not of interest to tools. */
typedef
   enum { 
      NoName,     /* Error case */
      ObjName,    /* Name is of an shared object file. */
      FunName,    /* Name is of a function. */
      DotDotDot   /* Frame-level wildcard */
   }
   SuppLocTy;

typedef
   struct {
      SuppLocTy ty;
      Bool      name_is_simple_str; /* True if name is a string without
                                       '?' and '*' wildcard characters. */
      HChar*    name; /* NULL for NoName and DotDotDot */
   }
   SuppLoc;

/* Suppressions.  Tools can get/set tool-relevant parts with functions
   declared in include/pub_tool_errormgr.h.  Extensible via the 'extra' field. 
   Tools can use a normal enum (with element values in the normal range
   (0..)) for 'skind'. */
struct _Supp {
   struct _Supp* next;
   Int count;     // The number of times this error has been suppressed.
   HChar* sname;  // The name by which the suppression is referred to.

   // Index in VG_(clo_suppressions) giving filename from which suppression
   // was read, and the lineno in this file where sname was read.
   Int    clo_suppressions_i;
   Int    sname_lineno;

   // Length of 'callers'
   Int n_callers;
   // Array of callers, for matching stack traces.  First one (name of fn
   // where err occurs) is mandatory;  rest are optional.
   SuppLoc* callers;

   /* The tool-specific part */
   SuppKind skind;   // What kind of suppression.  Must use the range (0..).
   HChar* string;    // String -- use is optional.  NULL by default.
   void* extra;      // Anything else -- use is optional.  NULL by default.
};

SuppKind VG_(get_supp_kind) ( Supp* su )
{
   return su->skind;
}

HChar* VG_(get_supp_string) ( Supp* su )
{
   return su->string;
}

void* VG_(get_supp_extra)  ( Supp* su )
{
   return su->extra;
}


void VG_(set_supp_kind)   ( Supp* su, SuppKind skind )
{
   su->skind = skind;
}

void VG_(set_supp_string) ( Supp* su, HChar* string )
{
   su->string = string;
}

void VG_(set_supp_extra)  ( Supp* su, void* extra )
{
   su->extra = extra;
}


/*------------------------------------------------------------*/
/*--- Helper fns                                           ---*/
/*------------------------------------------------------------*/

// Only show core errors if the tool wants to, we're not running with -q,
// and were not outputting XML.
Bool VG_(showing_core_errors)(void)
{
   return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
}

/* Compare errors, to detect duplicates. 
*/
static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
{
   if (e1->ekind != e2->ekind) 
      return False;
   if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
      return False;

   switch (e1->ekind) {
      //(example code, see comment on CoreSuppKind above)
      //case ThreadErr:
      //   vg_assert(VG_(needs).core_errors);
      //   return <something>
      default: 
         if (VG_(needs).tool_errors) {
            return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
         } else {
            VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
                        "probably needs to be set.\n",
                        e1->ekind);
            VG_(tool_panic)("unhandled error type");
         }
   }
}


/* Helper functions for suppression generation: print a single line of
   a suppression pseudo-stack-trace, either in XML or text mode.  It's
   important that the behaviour of these two functions exactly
   corresponds.
*/
#define ERRTXT_LEN   4096

static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
{
   static HChar buf[ERRTXT_LEN];
   InlIPCursor* iipc = VG_(new_IIPC)(ip);
   do {
      if ( VG_(get_fnname_no_cxx_demangle) (ip, buf,  ERRTXT_LEN, iipc) ) {
         VG_(printf_xml)("    <sframe> <fun>%pS</fun> </sframe>\n", buf);
      } else
      if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
         VG_(printf_xml)("    <sframe> <obj>%pS</obj> </sframe>\n", buf);
      } else {
         VG_(printf_xml)("    <sframe> <obj>*</obj> </sframe>\n");
      }
   } while (VG_(next_IIPC)(iipc));
   VG_(delete_IIPC)(iipc);
}

static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
{
   static HChar buf[ERRTXT_LEN];
   XArray* /* of HChar */ text = (XArray*)textV;
   InlIPCursor* iipc = VG_(new_IIPC)(ip);
   do {
      if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN, iipc) ) {
         VG_(xaprintf)(text, "   fun:%s\n", buf);
      } else
      if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
         VG_(xaprintf)(text, "   obj:%s\n", buf);
      } else {
         VG_(xaprintf)(text, "   obj:*\n");
      }
   } while (VG_(next_IIPC)(iipc));
   VG_(delete_IIPC)(iipc);
}

/* Generate a suppression for an error, either in text or XML mode.
*/
static void gen_suppression(Error* err)
{
   HChar       xtra[256]; /* assumed big enough (is overrun-safe) */
   Bool        anyXtra;
   const HChar* name;
   ExeContext* ec;
   XArray* /* HChar */ text;

   const HChar* dummy_name = "insert_a_suppression_name_here";

   vg_assert(err);

   ec = VG_(get_error_where)(err);
   vg_assert(ec);

   name = VG_TDICT_CALL(tool_get_error_name, err);
   if (NULL == name) {
      VG_(umsg)("(%s does not allow error to be suppressed)\n",
                VG_(details).name);
      return;
   }

   /* In XML mode, we also need to print the plain text version of the
      suppresion in a CDATA section.  What that really means is, we
      need to generate the plaintext version both in XML and text
      mode.  So generate it into TEXT. */
   text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
                      VG_(free), sizeof(HChar) );
   vg_assert(text);

   /* Ok.  Generate the plain text version into TEXT. */
   VG_(xaprintf)(text, "{\n");
   VG_(xaprintf)(text, "   <%s>\n", dummy_name);
   VG_(xaprintf)(text, "   %s:%s\n", VG_(details).name, name);

   VG_(memset)(xtra, 0, sizeof(xtra));
   anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
                           err, xtra, sizeof(xtra));
   vg_assert(xtra[sizeof(xtra)-1] == 0);

   if (anyXtra)
      VG_(xaprintf)(text, "   %s\n", xtra);

   // Print stack trace elements
   UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
   tl_assert(n_ips > 0);
   if (n_ips > VG_MAX_SUPP_CALLERS)
      n_ips = VG_MAX_SUPP_CALLERS;
   VG_(apply_StackTrace)(printSuppForIp_nonXML,
                         text,
                         VG_(get_ExeContext_StackTrace)(ec),
                         n_ips);

   VG_(xaprintf)(text, "}\n");
   // zero terminate
   VG_(xaprintf)(text, "%c", (HChar)0 );
   // VG_(printf) of text

   /* And now display it. */
   if (! VG_(clo_xml) ) {

      // the simple case
      VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );

   } else {

      /* Now we have to print the XML directly.  No need to go to the
         effort of stuffing it in an XArray, since we won't need it
         again. */
      VG_(printf_xml)("  <suppression>\n");
      VG_(printf_xml)("    <sname>%s</sname>\n", dummy_name);
      VG_(printf_xml)(
                      "    <skind>%pS:%pS</skind>\n", VG_(details).name, name);
      if (anyXtra)
         VG_(printf_xml)("    <skaux>%pS</skaux>\n", xtra);

      // Print stack trace elements
      VG_(apply_StackTrace)(printSuppForIp_XML,
                            NULL,
                            VG_(get_ExeContext_StackTrace)(ec),
                            VG_(get_ExeContext_n_ips)(ec));

      // And now the cdata bit
      // XXX FIXME!  properly handle the case where the raw text
      // itself contains "]]>", as specified in Protocol 4.
      VG_(printf_xml)("    <rawtext>\n");
      VG_(printf_xml)("<![CDATA[\n");
      VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
      VG_(printf_xml)("]]>\n");
      VG_(printf_xml)("    </rawtext>\n");
      VG_(printf_xml)("  </suppression>\n");

   }

   VG_(deleteXA)(text);
}


/* Figure out if we want to perform a given action for this error,
   possibly by asking the user.
*/
Bool VG_(is_action_requested) ( const HChar* action, Bool* clo )
{
   HChar ch, ch2;
   Int res;

   /* First off, we shouldn't be asking the user anything if
      we're in XML mode. */
   if (VG_(clo_xml))
      return False; /* That's a Nein, oder Nay as they say down here in B-W */

   if (*clo == False)
      return False;

   VG_(umsg)("\n");

  again:
   VG_(printf)(
      "==%d== "
      "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ", 
      VG_(getpid)(), action
   );

   res = VG_(read)(VG_(clo_input_fd), &ch, 1);
   if (res != 1) goto ioerror;
   /* res == 1 */
   if (ch == '\n') return False;
   if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y' 
      && ch != 'C' && ch != 'c') goto again;

   res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
   if (res != 1) goto ioerror;
   if (ch2 != '\n') goto again;

   /* No, don't want to do action. */
   if (ch == 'n' || ch == 'N') return False;
   /* Yes, want to do action. */
   if (ch == 'y' || ch == 'Y') return True;
   /* No, don't want to do action, and don't ask again either. */
   vg_assert(ch == 'c' || ch == 'C');

  ioerror:
   *clo = False;
   return False;
}


/* Do text-mode actions on error, that is, immediately after an error
   is printed.  These are:
   * possibly, attach to a debugger
   * possibly, generate a suppression.
   Note this should not be called in XML mode! 
*/
static 
void do_actions_on_error(Error* err, Bool allow_db_attach)
{
   Bool still_noisy = True;

   /* Should be assured by caller */
   vg_assert( ! VG_(clo_xml) );

   /* if user wants to debug from a certain error nr, then wait for gdb/vgdb */
   if (VG_(clo_vgdb) != Vg_VgdbNo
       && allow_db_attach 
       && VG_(dyn_vgdb_error) <= n_errs_shown) {
      VG_(umsg)("(action on error) vgdb me ... \n");
      VG_(gdbserver)( err->tid );
      VG_(umsg)("Continuing ...\n");
   }

   /* Perhaps we want a debugger attach at this point? */
   /* GDBTD ??? maybe we should/could remove the below assuming the
      gdbserver interface is better ??? */
   if (allow_db_attach &&
       VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
   {   
      if (0) VG_(printf)("starting debugger\n");
      VG_(start_debugger)( err->tid );
   }  
   /* Or maybe we want to generate the error's suppression? */
   if (VG_(clo_gen_suppressions) == 2
       || (VG_(clo_gen_suppressions) == 1
           && VG_(is_action_requested)( "Print suppression", &still_noisy ))
      ) {
      gen_suppression(err);
   }
   if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
      VG_(clo_gen_suppressions) = 0;
}


/* Prints an error.  Not entirely simple because of the differences
   between XML and text mode output.
 
   In XML mode:

   * calls the tool's pre-show method, so the tool can create any
     preamble ahead of the message, if it wants.

   * prints the opening tag, and the <unique> and <tid> fields

   * prints the tool-specific parts of the message

   * if suppression generation is required, a suppression

   * the closing tag

   In text mode:

   * calls the tool's pre-show method, so the tool can create any
     preamble ahead of the message, if it wants.

   * prints the tool-specific parts of the message

   * calls do_actions_on_error.  This optionally does a debugger
     attach (and detach), and optionally prints a suppression; both
     of these may require user input.
*/
static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
{
   /* If this fails, you probably specified your tool's method
      dictionary incorrectly. */
   vg_assert(VG_(needs).tool_errors);

   if (xml) {

      /* Note, allow_db_attach is ignored in here. */
 
      /* Ensure that suppression generation is either completely
         enabled or completely disabled; either way, we won't require
         any user input.  m_main.process_cmd_line_options should
         ensure the asserted condition holds. */
      vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
                 || VG_(clo_gen_suppressions) == 2 /* for all errors */ );

      /* Pre-show it to the tool */
      VG_TDICT_CALL( tool_before_pp_Error, err );
   
      /* standard preamble */
      VG_(printf_xml)("<error>\n");
      VG_(printf_xml)("  <unique>0x%x</unique>\n", err->unique);
      VG_(printf_xml)("  <tid>%d</tid>\n", err->tid);
      ThreadState* tst = VG_(get_ThreadState)(err->tid);
      if (tst->thread_name) {
         VG_(printf_xml)("  <threadname>%s</threadname>\n", tst->thread_name);
      }

      /* actually print it */
      VG_TDICT_CALL( tool_pp_Error, err );

      if (VG_(clo_gen_suppressions) > 0)
        gen_suppression(err);

      /* postamble */
      VG_(printf_xml)("</error>\n");
      VG_(printf_xml)("\n");

   } else {

      VG_TDICT_CALL( tool_before_pp_Error, err );

      if (VG_(tdict).tool_show_ThreadIDs_for_errors
          && err->tid > 0 && err->tid != last_tid_printed) {
         ThreadState* tst = VG_(get_ThreadState)(err->tid);
         if (tst->thread_name) {
            VG_(umsg)("Thread %d %s:\n", err->tid, tst->thread_name );
         } else {
            VG_(umsg)("Thread %d:\n", err->tid );
         }
         last_tid_printed = err->tid;
      }
   
      VG_TDICT_CALL( tool_pp_Error, err );
      VG_(umsg)("\n");

      do_actions_on_error(err, allow_db_attach);
   }
}


/* Construct an error */
static
void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
                       const HChar* s, void* extra, ExeContext* where )
{
   /* DO NOT MAKE unique_counter NON-STATIC */
   static UInt unique_counter = 0;

   tl_assert(tid < VG_N_THREADS);

   /* Core-only parts */
   err->unique   = unique_counter++;
   err->next     = NULL;
   err->supp     = NULL;
   err->count    = 1;
   err->tid      = tid;
   if (NULL == where)
     err->where = VG_(record_ExeContext)( tid, 0 );
   else
      err->where = where;

   /* Tool-relevant parts */
   err->ekind  = ekind;
   err->addr   = a;
   err->extra  = extra;
   err->string = s;

   /* sanity... */
   vg_assert( tid < VG_N_THREADS );
}



/* Top-level entry point to the error management subsystem.
   All detected errors are notified here; this routine decides if/when the
   user should see the error. */
void VG_(maybe_record_error) ( ThreadId tid, 
                               ErrorKind ekind, Addr a, const HChar* s, void* extra )
{
          Error  err;
          Error* p;
          Error* p_prev;
          UInt   extra_size;
          VgRes  exe_res          = Vg_MedRes;
   static Bool   stopping_message = False;
   static Bool   slowdown_message = False;

   /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
      been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
      have been found, just refuse to collect any more.  This stops
      the burden of the error-management system becoming excessive in
      extremely buggy programs, although it does make it pretty
      pointless to continue the Valgrind run after this point. */
   if (VG_(clo_error_limit) 
       && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
           || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
       && !VG_(clo_xml)) {
      if (!stopping_message) {
         VG_(umsg)("\n");

	 if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
            VG_(umsg)(
               "More than %d different errors detected.  "
               "I'm not reporting any more.\n",
               M_COLLECT_NO_ERRORS_AFTER_SHOWN );
         } else {
            VG_(umsg)(
               "More than %d total errors detected.  "
               "I'm not reporting any more.\n",
               M_COLLECT_NO_ERRORS_AFTER_FOUND );
	 }

         VG_(umsg)("Final error counts will be inaccurate.  "
                   "Go fix your program!\n");
         VG_(umsg)("Rerun with --error-limit=no to disable "
                   "this cutoff.  Note\n");
         VG_(umsg)("that errors may occur in your program without "
                   "prior warning from\n");
         VG_(umsg)("Valgrind, because errors are no longer "
                   "being displayed.\n");
         VG_(umsg)("\n");
         stopping_message = True;
      }
      return;
   }

   /* Ignore it if error acquisition is disabled for this thread. */
   { ThreadState* tst = VG_(get_ThreadState)(tid);
     if (tst->err_disablement_level > 0)
        return;
   }

   /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
      been found, be much more conservative about collecting new
      ones. */
   if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
       && !VG_(clo_xml)) {
      exe_res = Vg_LowRes;
      if (!slowdown_message) {
         VG_(umsg)("\n");
         VG_(umsg)("More than %d errors detected.  Subsequent errors\n",
                   M_COLLECT_ERRORS_SLOWLY_AFTER);
         VG_(umsg)("will still be recorded, but in less "
                   "detail than before.\n");
         slowdown_message = True;
      }
   }

   /* Build ourselves the error */
   construct_error ( &err, tid, ekind, a, s, extra, NULL );

   /* First, see if we've got an error record matching this one. */
   em_errlist_searches++;
   p       = errors;
   p_prev  = NULL;
   while (p != NULL) {
      em_errlist_cmps++;
      if (eq_Error(exe_res, p, &err)) {
         /* Found it. */
         p->count++;
	 if (p->supp != NULL) {
            /* Deal correctly with suppressed errors. */
            p->supp->count++;
            n_errs_suppressed++;	 
         } else {
            n_errs_found++;
         }

         /* Move p to the front of the list so that future searches
            for it are faster. It also allows to print the last
            error (see VG_(show_last_error). */
         if (p_prev != NULL) {
            vg_assert(p_prev->next == p);
            p_prev->next = p->next;
            p->next      = errors;
            errors       = p;
	 }

         return;
      }
      p_prev = p;
      p      = p->next;
   }

   /* Didn't see it.  Copy and add. */

   /* OK, we're really going to collect it.  The context is on the stack and
      will disappear shortly, so we must copy it.  First do the main
      (non-'extra') part.
     
      Then VG_(tdict).tool_update_extra can update the 'extra' part.  This
      is for when there are more details to fill in which take time to work
      out but don't affect our earlier decision to include the error -- by
      postponing those details until now, we avoid the extra work in the
      case where we ignore the error.  Ugly.

      Then, if there is an 'extra' part, copy it too, using the size that
      VG_(tdict).tool_update_extra returned.  Also allow for people using
      the void* extra field for a scalar value like an integer.
   */

   /* copy main part */
   p = VG_(malloc)("errormgr.mre.1", sizeof(Error));
   *p = err;

   /* update 'extra' */
   switch (ekind) {
      //(example code, see comment on CoreSuppKind above)
      //case ThreadErr:
      //   vg_assert(VG_(needs).core_errors);
      //   extra_size = <something>
      //   break;
      default:
         vg_assert(VG_(needs).tool_errors);
         extra_size = VG_TDICT_CALL(tool_update_extra, p);
         break;
   }

   /* copy block pointed to by 'extra', if there is one */
   if (NULL != p->extra && 0 != extra_size) { 
      void* new_extra = VG_(malloc)("errormgr.mre.2", extra_size);
      VG_(memcpy)(new_extra, p->extra, extra_size);
      p->extra = new_extra;
   }

   p->next = errors;
   p->supp = is_suppressible_error(&err);
   errors  = p;
   if (p->supp == NULL) {
      /* update stats */
      n_err_contexts++;
      n_errs_found++;
      n_errs_shown++;
      /* Actually show the error; more complex than you might think. */
      pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
   } else {
      n_supp_contexts++;
      n_errs_suppressed++;
      p->supp->count++;
   }
}

/* Second top-level entry point to the error management subsystem, for
   errors that the tool wants to report immediately, eg. because they're
   guaranteed to only happen once.  This avoids all the recording and
   comparing stuff.  But they can be suppressed;  returns True if it is
   suppressed.  Bool 'print_error' dictates whether to print the error. 
   Bool 'count_error' dictates whether to count the error in n_errs_found.
*/
Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, const HChar* s,
                         void* extra, ExeContext* where, Bool print_error,
                         Bool allow_db_attach, Bool count_error )
{
   Error err;
   Supp *su;

   /* Ignore it if error acquisition is disabled for this thread. */
   ThreadState* tst = VG_(get_ThreadState)(tid);
   if (tst->err_disablement_level > 0)
      return False; /* ignored, not suppressed */
   
   /* Build ourselves the error */
   construct_error ( &err, tid, ekind, a, s, extra, where );

   /* Unless it's suppressed, we're going to show it.  Don't need to make
      a copy, because it's only temporary anyway.

      Then update the 'extra' part with VG_(tdict).tool_update_extra),
      because that can have an affect on whether it's suppressed.  Ignore
      the size return value of VG_(tdict).tool_update_extra, because we're
      not copying 'extra'. */
   (void)VG_TDICT_CALL(tool_update_extra, &err);

   su = is_suppressible_error(&err);
   if (NULL == su) {
      if (count_error) {
         n_errs_found++;
         n_err_contexts++;
      }

      if (print_error) {
         /* update stats */
         n_errs_shown++;
         /* Actually show the error; more complex than you might think. */
         pp_Error(&err, allow_db_attach, VG_(clo_xml));
      }
      return False;

   } else {
      if (count_error) {
         n_errs_suppressed++;
         n_supp_contexts++;
      }
      su->count++;
      return True;
   }
}


/*------------------------------------------------------------*/
/*--- Exported fns                                         ---*/
/*------------------------------------------------------------*/

/* Show the used suppressions.  Returns False if no suppression
   got used. */
static Bool show_used_suppressions ( void )
{
   Supp  *su;
   Bool  any_supp;

   if (VG_(clo_xml))
      VG_(printf_xml)("<suppcounts>\n");

   any_supp = False;
   for (su = suppressions; su != NULL; su = su->next) {
      if (su->count <= 0)
         continue;
      if (VG_(clo_xml)) {
         VG_(printf_xml)( "  <pair>\n"
                                 "    <count>%d</count>\n"
                                 "    <name>%pS</name>\n"
                                 "  </pair>\n",
                                 su->count, su->sname );
      } else {
         HChar       xtra[256]; /* assumed big enough (is overrun-safe) */
         Bool        anyXtra;
         // blank line before the first shown suppression, if any
         if (!any_supp)
            VG_(dmsg)("\n");
         VG_(memset)(xtra, 0, sizeof(xtra));
         anyXtra = VG_TDICT_CALL(tool_print_extra_suppression_use,
                                 su, xtra, sizeof(xtra));
         vg_assert(xtra[sizeof(xtra)-1] == 0);
         VG_(dmsg)("used_suppression: %6d %s %s:%d%s%s\n", su->count, su->sname,
                   VG_(clo_suppressions)[su->clo_suppressions_i],
                   su->sname_lineno,
                   anyXtra ? " " : "", xtra);
      }
      any_supp = True;
   }

   if (VG_(clo_xml))
      VG_(printf_xml)("</suppcounts>\n");

   return any_supp;
}

/* Show all the errors that occurred, and possibly also the
   suppressions used. */
void VG_(show_all_errors) (  Int verbosity, Bool xml )
{
   Int    i, n_min;
   Error *p, *p_min;
   Bool   any_supp;

   if (verbosity == 0)
      return;

   /* If we're printing XML, just show the suppressions and stop. */
   if (xml) {
      (void)show_used_suppressions();
      return;
   }

   /* We only get here if not printing XML. */
   VG_(umsg)("ERROR SUMMARY: "
             "%d errors from %d contexts (suppressed: %d from %d)\n",
             n_errs_found, n_err_contexts, 
             n_errs_suppressed, n_supp_contexts );

   if (verbosity <= 1)
      return;

   // We do the following only at -v or above, and only in non-XML
   // mode

   /* Print the contexts in order of increasing error count. 
      Once an error is shown, we add a huge value to its count to filter it
      out.
      After having shown all errors, we reset count to the original value. */
   for (i = 0; i < n_err_contexts; i++) {
      n_min = (1 << 30) - 1;
      p_min = NULL;
      for (p = errors; p != NULL; p = p->next) {
         if (p->supp != NULL) continue;
         if (p->count < n_min) {
            n_min = p->count;
            p_min = p;
         }
      }
      // XXX: this isn't right.  See bug 203651.
      if (p_min == NULL) continue; //VG_(tool_panic)("show_all_errors()");

      VG_(umsg)("\n");
      VG_(umsg)("%d errors in context %d of %d:\n",
                p_min->count, i+1, n_err_contexts);
      pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );

      // We're not printing XML -- we'd have exited above if so.
      vg_assert(! xml);

      if ((i+1 == VG_(clo_dump_error))) {
         StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
         VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
                          ips[0], /*debugging*/True, 0xFE/*verbosity*/,
                          /*bbs_done*/0,
                          /*allow redir?*/True);
      }

      p_min->count = p_min->count + (1 << 30);
   } 

   /* reset the counts, otherwise a 2nd call does not show anything anymore */ 
   for (p = errors; p != NULL; p = p->next) {
      if (p->count >= (1 << 30))
         p->count = p->count - (1 << 30);
   }


   any_supp = show_used_suppressions();

   if (any_supp) 
      VG_(umsg)("\n");
   // reprint this, so users don't have to scroll way up to find
   // the first printing
   VG_(umsg)("ERROR SUMMARY: "
             "%d errors from %d contexts (suppressed: %d from %d)\n",
             n_errs_found, n_err_contexts, n_errs_suppressed,
             n_supp_contexts );
}

void VG_(show_last_error) ( void )
{
   if (n_err_contexts == 0) {
      VG_(umsg)("No errors yet\n");
      return;
   }

   pp_Error( errors, False/*allow_db_attach*/, False/*xml*/ );
}


/* Show occurrence counts of all errors, in XML form. */
void VG_(show_error_counts_as_XML) ( void )
{
   Error* err;
   VG_(printf_xml)("<errorcounts>\n");
   for (err = errors; err != NULL; err = err->next) {
      if (err->supp != NULL)
         continue;
      if (err->count <= 0)
         continue;
      VG_(printf_xml)("  <pair>\n");
      VG_(printf_xml)("    <count>%d</count>\n", err->count);
      VG_(printf_xml)("    <unique>0x%x</unique>\n", err->unique);
      VG_(printf_xml)("  </pair>\n");
   }
   VG_(printf_xml)("</errorcounts>\n");
   VG_(printf_xml)("\n");
}


/*------------------------------------------------------------*/
/*--- Suppression parsing                                  ---*/
/*------------------------------------------------------------*/

/* Get the next char from fd into *out_buf.  Returns 1 if success,
   0 if eof or < 0 if error. */

static Int get_char ( Int fd, HChar* out_buf )
{
   Int r;
   static HChar buf[256];
   static Int buf_size = 0;
   static Int buf_used = 0;
   vg_assert(buf_size >= 0 && buf_size <= 256);
   vg_assert(buf_used >= 0 && buf_used <= buf_size);
   if (buf_used == buf_size) {
      r = VG_(read)(fd, buf, 256);
      if (r < 0) return r; /* read failed */
      vg_assert(r >= 0 && r <= 256);
      buf_size = r;
      buf_used = 0;
   }
   if (buf_size == 0)
     return 0; /* eof */
   vg_assert(buf_size >= 0 && buf_size <= 256);
   vg_assert(buf_used >= 0 && buf_used < buf_size);
   *out_buf = buf[buf_used];
   buf_used++;
   return 1;
}

// Get a non blank non comment line.
// Returns True if eof.
static Bool get_nbnc_line ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
{
   HChar* buf  = *bufpp;
   SizeT nBuf = *nBufp;
   HChar  ch;
   Int   n, i;

   vg_assert(lineno); // lineno needed to correctly track line numbers.

   while (True) {
      buf[0] = 0;
      /* First, read until a non-blank char appears. */
      while (True) {
         n = get_char(fd, &ch);
         if (n == 1 && !VG_(isspace)(ch)) break;
         if (n == 1 && ch == '\n' && lineno)
            (*lineno)++;
         if (n <= 0) return True;
      }

      /* Now, read the line into buf. */
      i = 0;
      buf[i++] = ch; buf[i] = 0;
      while (True) {
         n = get_char(fd, &ch);
         if (n <= 0) return False; /* the next call will return True */
         if (ch == '\n' && lineno)
            (*lineno)++;
         if (ch == '\n') break;
         if (i > 0 && i == nBuf-1) {
            *nBufp = nBuf = nBuf * 2;
            #define RIDICULOUS   100000
            vg_assert2(nBuf < RIDICULOUS,  // Just a sanity check, really.
               "VG_(get_line): line longer than %d chars, aborting\n",
               RIDICULOUS);
            *bufpp = buf = VG_(realloc)("errormgr.get_line.1", buf, nBuf);
         }
         buf[i++] = ch; buf[i] = 0;
      }
      while (i > 1 && VG_(isspace)(buf[i-1])) { 
         i--; buf[i] = 0; 
      };

      // VG_(printf)("The line *%p %d is '%s'\n", lineno, *lineno, buf);
      /* Ok, we have a line.  If a non-comment line, return.
         If a comment line, start all over again. */
      if (buf[0] != '#') return False;
   }
}

// True if buf starts with fun: or obj: or is ...
static Bool is_location_line (HChar* buf)
{
   return VG_(strncmp)(buf, "fun:", 4) == 0
      || VG_(strncmp)(buf, "obj:", 4) == 0
      || VG_(strcmp)(buf, "...") == 0;
}

Bool VG_(get_line) ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
{
   Bool eof = get_nbnc_line (fd, bufpp, nBufp, lineno);

   if (eof)
      return True;

   if (is_location_line(*bufpp))
      return True; // Not a extra suppr line
   else
      return False; // A suppression extra line
}

/* True if s contains no wildcard (?, *) characters. */
static Bool is_simple_str (const HChar *s)
{
   while (*s) {
      if (*s == '?' || *s == '*')
         return False;
      s++;
   }
   return True;
}

/* buf contains the raw name of a caller, supposedly either
       fun:some_function_name   or
       obj:some_object_name     or
       ...
   Set p->ty and p->name accordingly.
   p->name is allocated and set to the string
   after the descriptor (fun: or obj:) part.
   Returns False if failed.
*/
static Bool setLocationTy ( SuppLoc* p, HChar *buf )
{
   if (VG_(strncmp)(buf, "fun:", 4) == 0) {
      p->name = VG_(arena_strdup)(VG_AR_CORE,
                                  "errormgr.sLTy.1", buf+4);
      p->name_is_simple_str = is_simple_str (p->name);
      p->ty = FunName;
      return True;
   }
   if (VG_(strncmp)(buf, "obj:", 4) == 0) {
      p->name = VG_(arena_strdup)(VG_AR_CORE,
                                  "errormgr.sLTy.2", buf+4);
      p->name_is_simple_str = is_simple_str (p->name);
      p->ty = ObjName;
      return True;
   }
   if (VG_(strcmp)(buf, "...") == 0) {
      p->name = NULL;
      p->name_is_simple_str = False;
      p->ty = DotDotDot;
      return True;
   }
   VG_(printf)("location should be \"...\", or should start "
               "with \"fun:\" or \"obj:\"\n");
   return False;
}


/* Look for "tool" in a string like "tool1,tool2,tool3" */
static Bool tool_name_present(const HChar *name, HChar *names)
{
   Bool  found;
   HChar *s = NULL;   /* Shut gcc up */
   Int   len = VG_(strlen)(name);

   found = (NULL != (s = VG_(strstr)(names, name)) &&
            (s        == names || *(s-1)   == ',') &&
            (*(s+len) == ','   || *(s+len) == '\0')
           );

   return found;
}

/* Read suppressions from the file specified in 
   VG_(clo_suppressions)[clo_suppressions_i]
   and place them in the suppressions list.  If there's any difficulty
   doing this, just give up -- there's no point in trying to recover.  
*/
static void load_one_suppressions_file ( Int clo_suppressions_i )
{
   const HChar* filename = VG_(clo_suppressions)[clo_suppressions_i];
   SysRes sres;
   Int    fd, i, j, lineno = 0;
   Bool   got_a_location_line_read_by_tool;
   Bool   eof;
   SizeT  nBuf = 200;
   HChar* buf = VG_(malloc)("errormgr.losf.1", nBuf);
   HChar* tool_names;
   HChar* supp_name;
   const HChar* err_str = NULL;
   SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];

   // Check it's not a directory.
   if (VG_(is_dir)( filename )) {
      if (VG_(clo_xml))
         VG_(printf_xml)("</valgrindoutput>\n");
      VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
      VG_(exit)(1);
   }

   // Open the suppression file.
   sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
   if (sr_isError(sres)) {
      if (VG_(clo_xml))
         VG_(printf_xml)("</valgrindoutput>\n");
      VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
      VG_(exit)(1);
   }
   fd = sr_Res(sres);

#  define BOMB(S)  { err_str = S;  goto syntax_error; }

   while (True) {
      /* Assign and initialise the two suppression halves (core and tool) */
      Supp* supp;
      supp        = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.1",
                                      sizeof(Supp));
      supp->count = 0;

      // Initialise temporary reading-in buffer.
      for (i = 0; i < VG_MAX_SUPP_CALLERS; i++) {
         tmp_callers[i].ty   = NoName;
         tmp_callers[i].name_is_simple_str = False;
         tmp_callers[i].name = NULL;
      }

      supp->string = supp->extra = NULL;

      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
      if (eof) {
         VG_(arena_free)(VG_AR_CORE, supp);
         break;
      }

      if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
      
      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );

      if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");

      supp->sname = VG_(arena_strdup)(VG_AR_CORE, "errormgr.losf.2", buf);
      supp->clo_suppressions_i = clo_suppressions_i;
      supp->sname_lineno = lineno;

      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );

      if (eof) BOMB("unexpected end-of-file (expecting tool:suppr)");

      /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
      i = 0;
      while (True) {
         if (buf[i] == ':')  break;
         if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
         i++;
      }
      buf[i]    = '\0';    /* Replace ':', splitting into two strings */

      tool_names = & buf[0];
      supp_name  = & buf[i+1];

      if (VG_(needs).core_errors && tool_name_present("core", tool_names))
      {
         // A core suppression
         //(example code, see comment on CoreSuppKind above)
         //if (VG_STREQ(supp_name, "Thread"))
         //   supp->skind = ThreadSupp;
         //else
            BOMB("unknown core suppression type");
      }
      else if (VG_(needs).tool_errors && 
               tool_name_present(VG_(details).name, tool_names))
      {
         // A tool suppression
         if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
            /* Do nothing, function fills in supp->skind */
         } else {
            BOMB("unknown tool suppression type");
         }
      }
      else {
         // Ignore rest of suppression
         while (True) {
            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
            if (eof) BOMB("unexpected end-of-file (when skipping suppression)");
            if (VG_STREQ(buf, "}"))
               break;
         }
         VG_(arena_free)(VG_AR_CORE, supp->sname);
         VG_(arena_free)(VG_AR_CORE, supp);
         continue;
      }

      buf[0] = 0;
      // tool_read_extra_suppression_info might read lines
      // from fd till a location line. 
      if (VG_(needs).tool_errors && 
          !VG_TDICT_CALL(tool_read_extra_suppression_info,
                         fd, &buf, &nBuf, &lineno, supp))
      {
         BOMB("bad or missing extra suppression info");
      }

      got_a_location_line_read_by_tool = buf[0] != 0 && is_location_line(buf);

      /* the main frame-descriptor reading loop */
      i = 0;
      while (True) {
         if (got_a_location_line_read_by_tool) {
            got_a_location_line_read_by_tool = False;
            eof = False;
         } else {
            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
         }
         if (eof)
            BOMB("unexpected end-of-file (when reading stack trace)");
         if (VG_STREQ(buf, "}")) {
            if (i > 0) {
               break;
            } else {
               BOMB("missing stack trace");
            }
         }
         if (i == VG_MAX_SUPP_CALLERS)
            BOMB("too many callers in stack trace");
         if (i > 0 && i >= VG_(clo_backtrace_size)) 
            break;
         if (!setLocationTy(&(tmp_callers[i]), buf))
            BOMB("location should be \"...\", or should start "
                 "with \"fun:\" or \"obj:\"");
         i++;
      }

      // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
      // lines and grab the '}'.
      if (!VG_STREQ(buf, "}")) {
         do {
            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
         } while (!eof && !VG_STREQ(buf, "}"));
      }

      // Reject entries which are entirely composed of frame
      // level wildcards.
      vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
      for (j = 0; j < i; j++) {
         if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
            break;
         vg_assert(tmp_callers[j].ty == DotDotDot);
      }
      vg_assert(j >= 0 && j <= i);
      if (j == i) {
         // we didn't find any non-"..." entries
         BOMB("suppression must contain at least one location "
              "line which is not \"...\"");
      } 

      // Copy tmp_callers[] into supp->callers[]
      supp->n_callers = i;
      supp->callers = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.4",
                                        i*sizeof(SuppLoc));
      for (i = 0; i < supp->n_callers; i++) {
         supp->callers[i] = tmp_callers[i];
      }

      supp->next = suppressions;
      suppressions = supp;
   }
   VG_(free)(buf);
   VG_(close)(fd);
   return;

  syntax_error:
   if (VG_(clo_xml))
      VG_(printf_xml)("</valgrindoutput>\n");
   VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
           filename, lineno );
   VG_(umsg)("   %s\n", err_str );
   
   VG_(close)(fd);
   VG_(umsg)("exiting now.\n");
   VG_(exit)(1);

#  undef BOMB
}


void VG_(load_suppressions) ( void )
{
   Int i;
   suppressions = NULL;
   for (i = 0; i < VG_(clo_n_suppressions); i++) {
      if (VG_(clo_verbosity) > 1) {
         VG_(dmsg)("Reading suppressions file: %s\n", 
                   VG_(clo_suppressions)[i] );
      }
      load_one_suppressions_file( i );
   }
}


/*------------------------------------------------------------*/
/*--- Matching errors to suppressions                      ---*/
/*------------------------------------------------------------*/

/* Parameterising functions for the use of VG_(generic_match) in
   suppression-vs-error matching.  The suppression frames (SuppLoc)
   play the role of 'pattern'-element, and the error frames (IPs,
   hence simply Addrs) play the role of 'input'.  In short then, we're
   matching a sequence of Addrs against a pattern composed of a
   sequence of SuppLocs.
*/
static Bool supploc_IsStar ( const void* supplocV )
{
   const SuppLoc* supploc = supplocV;
   return supploc->ty == DotDotDot;
}

static Bool supploc_IsQuery ( const void* supplocV )
{
   return False; /* there's no '?' equivalent in the supp syntax */
}

/* IPtoFunOrObjCompleter is a lazy completer of the IPs
   needed to match an error with the suppression patterns.
   The matching between an IP and a suppression pattern is done either
   with the IP function name or with the IP object name.
   First time the fun or obj name is needed for an IP member
   of a stack trace, it will be computed and stored in names.
   Also, if the IP corresponds to one or more inlined function calls,
   the inlined function names are expanded.
   The IPtoFunOrObjCompleter type is designed to minimise the nr of
   allocations and the nr of debuginfo search. */
typedef
   struct {
      StackTrace ips; // stack trace we are lazily completing.
      UWord n_ips; // nr of elements in ips.

      // VG_(generic_match) calls haveInputInpC to check
      // for the presence of an input element identified by ixInput
      // (i.e. a number that identifies the ixInput element of the
      // input sequence). It calls supp_pattEQinp to match this input
      // element with a pattern.
      // When inlining info is used to provide inlined function calls
      // in stacktraces, one IP in ips can be expanded in several
      // function names. So, each time input (or presence of input)
      // is requested by VG_(generic_match), we will expand
      // more IP of ips till we have expanded enough to reach the
      // input element requested (or we cannot expand anymore).

      UWord n_ips_expanded;
      // n_ips_expanded maintains the nr of elements in ips that we have
      // already expanded.
      UWord n_expanded;
      // n_expanded maintains the nr of elements resulting from the expansion
      // of the n_ips_expanded IPs. Without inlined function calls,
      // n_expanded == n_ips_expanded. With inlining info,
      // n_expanded >= n_ips_expanded.

      Int* n_offsets_per_ip;
      // n_offsets_per_ip[i] gives the nr of offsets in fun_offsets and obj_offsets
      // resulting of the expansion of ips[i].
      // The sum of all n_expanded_per_ip must be equal to n_expanded.
      // This array allows to retrieve the position in ips corresponding to an ixInput.

      // size (in elements) of fun_offsets and obj_offsets.
      // (fun|obj)_offsets are reallocated if more space is needed
      // to expand an IP.
      UWord sz_offsets;

      Int* fun_offsets;
      // fun_offsets[ixInput] is the offset in names where the
      // function name for the ixInput element of the input sequence
      // can be found. As one IP of ips can be expanded in several
      // function calls due to inlined function calls, we can have more
      // elements in fun_offsets than in ips.
      // An offset -1 means the function name has not yet been computed.
      Int* obj_offsets;
      // Similarly, obj_offsets[ixInput] gives the offset for the
      // object name for ips[ixInput]
      // (-1 meaning object name not yet been computed).

      // All function names and object names will be concatenated
      // in names. names is reallocated on demand.
      HChar *names;
      Int   names_szB;  // size of names.
      Int   names_free; // offset first free HChar in names.
   }
   IPtoFunOrObjCompleter;

// free the memory in ip2fo.
static void clearIPtoFunOrObjCompleter
  (IPtoFunOrObjCompleter* ip2fo)
{
   if (ip2fo->n_offsets_per_ip) VG_(free)(ip2fo->n_offsets_per_ip);
   if (ip2fo->fun_offsets)      VG_(free)(ip2fo->fun_offsets);
   if (ip2fo->obj_offsets)      VG_(free)(ip2fo->obj_offsets);
   if (ip2fo->names)            VG_(free)(ip2fo->names);
}

/* Grow ip2fo->names to ensure we have ERRTXT_LEN characters available
   in ip2fo->names and returns a pointer to the first free char. */
static HChar* grow_names(IPtoFunOrObjCompleter* ip2fo)
{
   if (ip2fo->names_szB 
       < ip2fo->names_free + ERRTXT_LEN) {
      ip2fo->names 
         = VG_(realloc)("foc_names",
                        ip2fo->names,
                        ip2fo->names_szB + ERRTXT_LEN);
      ip2fo->names_szB += ERRTXT_LEN;
   }
   return ip2fo->names + ip2fo->names_free;
}

/* foComplete returns the function name or object name for ixInput.
   If needFun, returns the function name for this input
   else returns the object name for this input.
   The function name or object name will be computed and added in
   names if not yet done. */
static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo,
                         Int ixInput, Bool needFun)
{
   vg_assert (ixInput < ip2fo->n_expanded);
   vg_assert (VG_(clo_read_inline_info) || ixInput < ip2fo->n_ips);

   // ptr to the offset array for function offsets (if needFun)
   // or object offsets (if !needFun).
   Int** offsets;
   if (needFun)
      offsets = &ip2fo->fun_offsets;
   else
      offsets = &ip2fo->obj_offsets;

   // Complete Fun name or Obj name for IP if not yet done.
   if ((*offsets)[ixInput] == -1) {
      HChar* caller_name = grow_names(ip2fo);
      (*offsets)[ixInput] = ip2fo->names_free;
      if (needFun) {
         // With inline info, fn names must have been completed already.
         vg_assert (!VG_(clo_read_inline_info));
         /* Get the function name into 'caller_name', or "???"
            if unknown. */
         // Nb: C++-mangled names are used in suppressions.  Do, though,
         // Z-demangle them, since otherwise it's possible to wind
         // up comparing "malloc" in the suppression against
         // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
         // two of them need to be made to match.
         if (!VG_(get_fnname_no_cxx_demangle)(ip2fo->ips[ixInput],
                                              caller_name, ERRTXT_LEN,
                                              NULL))
            VG_(strcpy)(caller_name, "???");
      } else {
         /* Get the object name into 'caller_name', or "???"
            if unknown. */
         UWord i;
         UWord last_expand_pos_ips = 0;
         UWord pos_ips;

         /* First get the pos in ips corresponding to ixInput */
         for (pos_ips = 0; pos_ips < ip2fo->n_expanded; pos_ips++) {
            last_expand_pos_ips += ip2fo->n_offsets_per_ip[pos_ips];
            if (ixInput <= last_expand_pos_ips)
               break;
         }
         /* pos_ips is the position in ips corresponding to ixInput.
            last_expand_pos_ips is the last offset in fun/obj where
            ips[pos_ips] has been expanded. */

         if (!VG_(get_objname)(ip2fo->ips[pos_ips], caller_name, ERRTXT_LEN))
            VG_(strcpy)(caller_name, "???");

         // Have all inlined calls pointing at this object name
         for (i = last_expand_pos_ips - ip2fo->n_offsets_per_ip[pos_ips] - 1;
              i <= last_expand_pos_ips;
              i++)
            ip2fo->obj_offsets[i] = ip2fo->names_free;
      }
      ip2fo->names_free += VG_(strlen)(caller_name) + 1;
   }

   return ip2fo->names + (*offsets)[ixInput];
}

// Grow fun and obj _offsets arrays to have at least n_req elements.
// Ensure n_offsets_per_ip is allocated.
static void grow_offsets(IPtoFunOrObjCompleter* ip2fo, Int n_req)
{
   Int i;

   // n_offsets_per_ip must always have the size of the ips array
   if (ip2fo->n_offsets_per_ip == NULL) {
      ip2fo->n_offsets_per_ip = VG_(malloc)("grow_offsets",
                                            ip2fo->n_ips * sizeof(Int));
      for (i = 0; i < ip2fo->n_ips; i++)
         ip2fo->n_offsets_per_ip[i] = 0;
   }

   if (ip2fo->sz_offsets >= n_req)
      return;

   // Avoid too much re-allocation by allocating at least ip2fo->n_ips
   // elements and at least a few more elements than the current size.
   if (n_req < ip2fo->n_ips)
      n_req = ip2fo->n_ips;
   if (n_req < ip2fo->sz_offsets + 5)
      n_req = ip2fo->sz_offsets + 5;

   ip2fo->fun_offsets = VG_(realloc)("grow_offsets", ip2fo->fun_offsets,
                                     n_req * sizeof(Int));
   for (i = ip2fo->sz_offsets; i < n_req; i++)
      ip2fo->fun_offsets[i] = -1;

   ip2fo->obj_offsets = VG_(realloc)("grow_offsets", ip2fo->obj_offsets,
                                     n_req * sizeof(Int));
   for (i = ip2fo->sz_offsets; i < n_req; i++)
      ip2fo->obj_offsets[i] = -1;

   ip2fo->sz_offsets = n_req;   
}

// Expands more IPs from ip2fo->ips.
static void expandInput (IPtoFunOrObjCompleter* ip2fo, UWord ixInput )
{
   while (ip2fo->n_ips_expanded < ip2fo->n_ips
          && ip2fo->n_expanded <= ixInput) {
      if (VG_(clo_read_inline_info)) {
         // Expand one more IP in one or more calls.
         const Addr IP = ip2fo->ips[ip2fo->n_ips_expanded];
         InlIPCursor *iipc;

         iipc = VG_(new_IIPC)(IP);
         // The only thing we really need is the nr of inlined fn calls
         // corresponding to the IP we will expand.
         // However, computing this is mostly the same as finding
         // the function name. So, let's directly complete the function name.
         do {
            HChar* caller_name = grow_names(ip2fo);
            grow_offsets(ip2fo, ip2fo->n_expanded+1);
            ip2fo->fun_offsets[ip2fo->n_expanded] = ip2fo->names_free;
            if (!VG_(get_fnname_no_cxx_demangle)(IP, 
                                                 caller_name, ERRTXT_LEN,
                                                 iipc))
               VG_(strcpy)(caller_name, "???");
            ip2fo->names_free += VG_(strlen)(caller_name) + 1;
            ip2fo->n_expanded++;
            ip2fo->n_offsets_per_ip[ip2fo->n_ips_expanded]++;
         } while (VG_(next_IIPC)(iipc));
         ip2fo->n_ips_expanded++;
         VG_(delete_IIPC) (iipc);
      } else {
         // Without inlined fn call info, expansion simply
         // consists in allocating enough elements in (fun|obj)_offsets.
         // The function or object names themselves will be completed
         // when requested.
         Int i;
         grow_offsets(ip2fo, ip2fo->n_ips);
         ip2fo->n_ips_expanded = ip2fo->n_ips;
         ip2fo->n_expanded = ip2fo->n_ips;
         for (i = 0; i < ip2fo->n_ips; i++)
            ip2fo->n_offsets_per_ip[i] = 1;
      }
   }
}

static Bool haveInputInpC (void* inputCompleter, UWord ixInput )
{
   IPtoFunOrObjCompleter* ip2fo = inputCompleter;
   expandInput(ip2fo, ixInput);
   return ixInput < ip2fo->n_expanded;
}

static Bool supp_pattEQinp ( const void* supplocV, const void* addrV,
                             void* inputCompleter, UWord ixInput )
{
   const SuppLoc* supploc = supplocV; /* PATTERN */
   IPtoFunOrObjCompleter* ip2fo = inputCompleter;
   HChar* funobj_name; // Fun or Obj name.

   expandInput(ip2fo, ixInput);
   vg_assert(ixInput < ip2fo->n_expanded);

   /* So, does this IP address match this suppression-line? */
   switch (supploc->ty) {
      case DotDotDot:
         /* supp_pattEQinp is a callback from VG_(generic_match).  As
            per the spec thereof (see include/pub_tool_seqmatch.h), we
            should never get called with a pattern value for which the
            _IsStar or _IsQuery function would return True.  Hence
            this can't happen. */
         vg_assert(0);
      case ObjName:
         funobj_name = foComplete(ip2fo, ixInput, False /*needFun*/);
         break; 
      case FunName:
         funobj_name = foComplete(ip2fo, ixInput, True /*needFun*/);
         break;
      default:
        vg_assert(0);
   }

   /* So now we have the function or object name in funobj_name, and
      the pattern (at the character level) to match against is in
      supploc->name.  Hence (and leading to a re-entrant call of
      VG_(generic_match) if there is a wildcard character): */
   if (supploc->name_is_simple_str)
      return VG_(strcmp) (supploc->name, funobj_name) == 0;
   else
      return VG_(string_match)(supploc->name, funobj_name);
}

/////////////////////////////////////////////////////

static Bool supp_matches_callers(IPtoFunOrObjCompleter* ip2fo, Supp* su)
{
   /* Unwrap the args and set up the correct parameterisation of
      VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
      supp_pattEQinp. */
   /* note, StackTrace ip2fo->ips === Addr* */
   SuppLoc*   supps    = su->callers;
   UWord      n_supps  = su->n_callers;
   UWord      szbPatt  = sizeof(SuppLoc);
   Bool       matchAll = False; /* we just want to match a prefix */
   return
      VG_(generic_match)(
         matchAll,
         /*PATT*/supps, szbPatt, n_supps, 0/*initial ixPatt*/,
         /*INPUT*/
         NULL, 0, 0, /* input/szbInput/nInput 0, as using an inputCompleter */  
         0/*initial ixInput*/,
         supploc_IsStar, supploc_IsQuery, supp_pattEQinp,
         ip2fo, haveInputInpC
      );
}

/////////////////////////////////////////////////////

static
Bool supp_matches_error(Supp* su, Error* err)
{
   switch (su->skind) {
      //(example code, see comment on CoreSuppKind above)
      //case ThreadSupp:
      //   return (err->ekind == ThreadErr);
      default:
         if (VG_(needs).tool_errors) {
            return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
         } else {
            VG_(printf)(
               "\nUnhandled suppression type: %u.  VG_(needs).tool_errors\n"
               "probably needs to be set.\n",
               err->ekind);
            VG_(tool_panic)("unhandled suppression type");
         }
   }
}

/////////////////////////////////////////////////////

/* Does an error context match a suppression?  ie is this a suppressible
   error?  If so, return a pointer to the Supp record, otherwise NULL.
   Tries to minimise the number of symbol searches since they are expensive.  
*/
static Supp* is_suppressible_error ( Error* err )
{
   Supp* su;
   Supp* su_prev;

   IPtoFunOrObjCompleter ip2fo;
   /* Conceptually, ip2fo contains an array of function names and an array of
      object names, corresponding to the array of IP of err->where.
      These names are just computed 'on demand' (so once maximum),
      then stored (efficiently, avoiding too many allocs) in ip2fo to be
      re-usable for the matching of the same IP with the next suppression
      pattern. 

      VG_(generic_match) gets this 'IP to Fun or Obj name completer' as one
      of its arguments. It will then pass it to the function
      supp_pattEQinp which will then lazily complete the IP function name or
      object name inside ip2fo. Next time the fun or obj name for the same
      IP is needed (i.e. for the matching with the next suppr pattern), then
      the fun or obj name will not be searched again in the debug info. */

   /* stats gathering */
   em_supplist_searches++;

   /* Prepare the lazy input completer. */
   ip2fo.ips = VG_(get_ExeContext_StackTrace)(err->where);
   ip2fo.n_ips = VG_(get_ExeContext_n_ips)(err->where);
   ip2fo.n_ips_expanded = 0;
   ip2fo.n_expanded = 0;
   ip2fo.sz_offsets = 0;
   ip2fo.n_offsets_per_ip = NULL;
   ip2fo.fun_offsets = NULL;
   ip2fo.obj_offsets = NULL;
   ip2fo.names = NULL;
   ip2fo.names_szB = 0;
   ip2fo.names_free = 0;

   /* See if the error context matches any suppression. */
   su_prev = NULL;
   for (su = suppressions; su != NULL; su = su->next) {
      em_supplist_cmps++;
      if (supp_matches_error(su, err) 
          && supp_matches_callers(&ip2fo, su)) {
         /* got a match.  */
         /* Inform the tool that err is suppressed by su. */
         (void)VG_TDICT_CALL(tool_update_extra_suppression_use, err, su);
         /* Move this entry to the head of the list
            in the hope of making future searches cheaper. */
         if (su_prev) {
            vg_assert(su_prev->next == su);
            su_prev->next = su->next;
            su->next = suppressions;
            suppressions = su;
         }
         clearIPtoFunOrObjCompleter(&ip2fo);
         return su;
      }
      su_prev = su;
   }
   clearIPtoFunOrObjCompleter(&ip2fo);
   return NULL;      /* no matches */
}

/* Show accumulated error-list and suppression-list search stats. 
*/
void VG_(print_errormgr_stats) ( void )
{
   VG_(dmsg)(
      " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
      em_supplist_searches, em_supplist_cmps
   );
   VG_(dmsg)(
      " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
      em_errlist_searches, em_errlist_cmps
   );
}

/*--------------------------------------------------------------------*/
/*--- end                                                          ---*/
/*--------------------------------------------------------------------*/
