1de4a1d01951937632098a6cda45859afa587a06fsewardj
2de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/
3267100d2a8495dd214d4f55351c469c23a18391dsewardj/*--- Management of error messages.                   m_errormgr.c ---*/
4de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/
5de4a1d01951937632098a6cda45859afa587a06fsewardj
6de4a1d01951937632098a6cda45859afa587a06fsewardj/*
7b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   This file is part of Valgrind, a dynamic binary instrumentation
8b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   framework.
9de4a1d01951937632098a6cda45859afa587a06fsewardj
10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2000-2017 Julian Seward
11de4a1d01951937632098a6cda45859afa587a06fsewardj      jseward@acm.org
12de4a1d01951937632098a6cda45859afa587a06fsewardj
13de4a1d01951937632098a6cda45859afa587a06fsewardj   This program is free software; you can redistribute it and/or
14de4a1d01951937632098a6cda45859afa587a06fsewardj   modify it under the terms of the GNU General Public License as
15de4a1d01951937632098a6cda45859afa587a06fsewardj   published by the Free Software Foundation; either version 2 of the
16de4a1d01951937632098a6cda45859afa587a06fsewardj   License, or (at your option) any later version.
17de4a1d01951937632098a6cda45859afa587a06fsewardj
18de4a1d01951937632098a6cda45859afa587a06fsewardj   This program is distributed in the hope that it will be useful, but
19de4a1d01951937632098a6cda45859afa587a06fsewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20de4a1d01951937632098a6cda45859afa587a06fsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21de4a1d01951937632098a6cda45859afa587a06fsewardj   General Public License for more details.
22de4a1d01951937632098a6cda45859afa587a06fsewardj
23de4a1d01951937632098a6cda45859afa587a06fsewardj   You should have received a copy of the GNU General Public License
24de4a1d01951937632098a6cda45859afa587a06fsewardj   along with this program; if not, write to the Free Software
25de4a1d01951937632098a6cda45859afa587a06fsewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26de4a1d01951937632098a6cda45859afa587a06fsewardj   02111-1307, USA.
27de4a1d01951937632098a6cda45859afa587a06fsewardj
28e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   The GNU General Public License is contained in the file COPYING.
29de4a1d01951937632098a6cda45859afa587a06fsewardj*/
30de4a1d01951937632098a6cda45859afa587a06fsewardj
31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h"
324cfea4f9480393ed6799db463b2e0fb8865a1a2fsewardj#include "pub_core_vki.h"
3324a6efb2f94eb0cb5d53174d580e1dc00893a6d6njn#include "pub_core_threadstate.h"      // For VG_N_THREADS
34ea27e4627518665dd6c81213c0ba1f7ff0218e1anjn#include "pub_core_debuginfo.h"
355ab7ce8534933940ae16c11a98939f4dc930c62dphilippe#include "pub_core_debuglog.h"
36d2b1711bd846d1eb4dcb7b05a44a2bfbb49a5992njn#include "pub_core_errormgr.h"
37d01fef7de693582a6ce32bdbef7c9040ad6b356bnjn#include "pub_core_execontext.h"
383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include "pub_core_gdbserver.h"
3997405b2d134b52880d6dbec3eb2929e2002c2542njn#include "pub_core_libcbase.h"
40132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_core_libcassert.h"
41eb8896b58301a0a7a34281384d705072994369f0njn#include "pub_core_libcfile.h"
4236a20fa5f779a0a6fb7b4a90dcaa6376481f1faanjn#include "pub_core_libcprint.h"
4324a6efb2f94eb0cb5d53174d580e1dc00893a6d6njn#include "pub_core_libcproc.h"         // For VG_(getpid)()
44d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj#include "pub_core_seqmatch.h"
45af1d7dfc9412c09d24ea10118f3fd1082f92e49dnjn#include "pub_core_mallocfree.h"
462024234c590f408994b373abfb00bc2cd2a90c48njn#include "pub_core_options.h"
47d0d7c1fc4e59b97115620fdae795f1128bda2d31njn#include "pub_core_stacktrace.h"
4843b9a8abb139b86a24457fa3c19b9cb60ca17c3anjn#include "pub_core_tooliface.h"
4924a6efb2f94eb0cb5d53174d580e1dc00893a6d6njn#include "pub_core_translate.h"        // for VG_(translate)()
50588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj#include "pub_core_xarray.h"           // VG_(xaprintf) et al
51de4a1d01951937632098a6cda45859afa587a06fsewardj
525ab7ce8534933940ae16c11a98939f4dc930c62dphilippe#define DEBUG_ERRORMGR 0 // set to 1 for heavyweight tracing
535ab7ce8534933940ae16c11a98939f4dc930c62dphilippe
54de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/*--- Globals                                              ---*/
56de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
57de4a1d01951937632098a6cda45859afa587a06fsewardj
5814319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn/* After this many different unsuppressed errors have been observed,
5914319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   be more conservative about collecting new ones. */
601d1a226e21cc1e6d9d104ee18a2c74e86755b595sewardj#define M_COLLECT_ERRORS_SLOWLY_AFTER 100
6114319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn
6214319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn/* After this many different unsuppressed errors have been observed,
6314319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   stop collecting errors at all, and tell the user their program is
6414319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   evidently a steaming pile of camel dung. */
651d1a226e21cc1e6d9d104ee18a2c74e86755b595sewardj#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000
6614319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn
6714319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn/* After this many total errors have been observed, stop collecting
6814319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   errors at all.  Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
69513646f829e6b0ca344f39278ebdd6503021adbfsewardj#define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000
7014319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn
71de4a1d01951937632098a6cda45859afa587a06fsewardj/* The list of error contexts found, both suppressed and unsuppressed.
72de4a1d01951937632098a6cda45859afa587a06fsewardj   Initially empty, and grows as errors are detected. */
73695c16e4b8b6d09a2c8127f6a0015b45d6194b88njnstatic Error* errors = NULL;
74de4a1d01951937632098a6cda45859afa587a06fsewardj
75de4a1d01951937632098a6cda45859afa587a06fsewardj/* The list of suppression directives, as read from the specified
768a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   suppressions file.  Note that the list gets rearranged as a result
778a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   of the searches done by is_suppressible_error(). */
78695c16e4b8b6d09a2c8127f6a0015b45d6194b88njnstatic Supp* suppressions = NULL;
79de4a1d01951937632098a6cda45859afa587a06fsewardj
80de4a1d01951937632098a6cda45859afa587a06fsewardj/* Running count of unsuppressed errors detected. */
81f2b1148e1dfea70023f57f81b6ced770f3c22231nethercotestatic UInt n_errs_found = 0;
82de4a1d01951937632098a6cda45859afa587a06fsewardj
83de4a1d01951937632098a6cda45859afa587a06fsewardj/* Running count of suppressed errors detected. */
84f2b1148e1dfea70023f57f81b6ced770f3c22231nethercotestatic UInt n_errs_suppressed = 0;
85de4a1d01951937632098a6cda45859afa587a06fsewardj
86baf69645a5d270e6662d05d74e537e9ba970f34cphilippe/* Running count of errors shown. */
87baf69645a5d270e6662d05d74e537e9ba970f34cphilippestatic UInt n_errs_shown = 0;
88baf69645a5d270e6662d05d74e537e9ba970f34cphilippe
89606a4aeacb004873d2839467e2ad0ab3aabc8c27njn/* Running count of unsuppressed error contexts. */
90606a4aeacb004873d2839467e2ad0ab3aabc8c27njnstatic UInt n_err_contexts = 0;
91606a4aeacb004873d2839467e2ad0ab3aabc8c27njn
92606a4aeacb004873d2839467e2ad0ab3aabc8c27njn/* Running count of suppressed error contexts. */
93606a4aeacb004873d2839467e2ad0ab3aabc8c27njnstatic UInt n_supp_contexts = 0;
94606a4aeacb004873d2839467e2ad0ab3aabc8c27njn
95606a4aeacb004873d2839467e2ad0ab3aabc8c27njn
96de4a1d01951937632098a6cda45859afa587a06fsewardj/* forwards ... */
97518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Supp* is_suppressible_error ( const Error* err );
98de4a1d01951937632098a6cda45859afa587a06fsewardj
99b5f6f51ebcac183818061bf53427a3e7808ef10dsewardjstatic ThreadId last_tid_printed = 1;
100de4a1d01951937632098a6cda45859afa587a06fsewardj
1018a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Stats: number of searches of the error list initiated. */
1028a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardjstatic UWord em_errlist_searches = 0;
1038a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
1048a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Stats: number of comparisons done during error list
1058a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   searching. */
1068a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardjstatic UWord em_errlist_cmps = 0;
1078a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
1088a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Stats: number of searches of the suppression list initiated. */
1098a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardjstatic UWord em_supplist_searches = 0;
1108a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
1118a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Stats: number of comparisons done during suppression list
1128a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   searching. */
1138a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardjstatic UWord em_supplist_cmps = 0;
1148a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
115de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
1164a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*--- Error type                                           ---*/
1174a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*------------------------------------------------------------*/
1184a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1194a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/* Errors.  Extensible (via the 'extra' field).  Tools can use a normal
12002bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn   enum (with element values in the normal range (0..)) for 'ekind'.
1214a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Functions for getting/setting the tool-relevant fields are in
122c7561b931e249acf3768ead77638545b0ccaa8f1njn   include/pub_tool_errormgr.h.
1234a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1244a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   When errors are found and recorded with VG_(maybe_record_error)(), all
1254a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   the tool must do is pass in the four parameters;  core will
1264a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   allocate/initialise the error record.
1274a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote*/
1284a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotestruct _Error {
1294a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   struct _Error* next;
130dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   // Unique tag.  This gives the error a unique identity (handle) by
131dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   // which it can be referred to afterwords.  Currently only used for
132dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   // XML printing.
133dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   UInt unique;
1344a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   // NULL if unsuppressed; or ptr to suppression record.
1354a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Supp* supp;
1364a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Int count;
1374a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1384a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   // The tool-specific part
139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ThreadId tid;           // Initialised by core
1404a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   ExeContext* where;      // Initialised by core
141d2b1711bd846d1eb4dcb7b05a44a2bfbb49a5992njn   ErrorKind ekind;        // Used by ALL.  Must be in the range (0..)
1424a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Addr addr;              // Used frequently
143e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian   const HChar* string;    // Used frequently
1444a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   void* extra;            // For any tool-specific extras
1454a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote};
1464a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1488e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianExeContext* VG_(get_error_where) ( const Error* err )
1494a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
1504a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return err->where;
1514a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
1524a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1538e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianErrorKind VG_(get_error_kind) ( const Error* err )
1544a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
1554a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return err->ekind;
1564a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
1574a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1588e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianAddr VG_(get_error_address) ( const Error* err )
1594a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
1604a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return err->addr;
1614a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
1624a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1638e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianconst HChar* VG_(get_error_string) ( const Error* err )
1644a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
1654a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return err->string;
1664a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
1674a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1688e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid* VG_(get_error_extra)  ( const Error* err )
1694a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
1704a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return err->extra;
1714a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
1724a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
173f2b1148e1dfea70023f57f81b6ced770f3c22231nethercoteUInt VG_(get_n_errs_found)( void )
174f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote{
175f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote   return n_errs_found;
176f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote}
177f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote
178baf69645a5d270e6662d05d74e537e9ba970f34cphilippeUInt VG_(get_n_errs_shown)( void )
179baf69645a5d270e6662d05d74e537e9ba970f34cphilippe{
180baf69645a5d270e6662d05d74e537e9ba970f34cphilippe   return n_errs_shown;
181baf69645a5d270e6662d05d74e537e9ba970f34cphilippe}
182baf69645a5d270e6662d05d74e537e9ba970f34cphilippe
1834a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*------------------------------------------------------------*/
1844a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*--- Suppression type                                     ---*/
1854a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*------------------------------------------------------------*/
1864a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
1874a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/* Note: it is imperative this doesn't overlap with (0..) at all, as tools
1884a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote * effectively extend it by defining their own enums in the (0..) range. */
1894a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotetypedef
1904a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   enum {
191a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      // Nb: thread errors are a relic of the time when Valgrind's core
192a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      // could detect them.  This example is left commented-out as an
193a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      // example should new core errors ever be added.
194a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      ThreadSupp = -1,    /* Matches ThreadErr */
1954a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   }
1964a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   CoreSuppKind;
1974a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
198a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes/* Max number of callers for context in a suppression is
199a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes   VG_DEEPEST_BACKTRACE. */
200b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
2014a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/* For each caller specified for a suppression, record the nature of
2024a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   the caller name.  Not of interest to tools. */
2034a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotetypedef
2044a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   enum {
205b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      NoName,     /* Error case */
2064a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote      ObjName,    /* Name is of an shared object file. */
2075e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      FunName,    /* Name is of a function. */
2085e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      DotDotDot   /* Frame-level wildcard */
2094a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   }
2104a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   SuppLocTy;
2114a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
212b5f6f51ebcac183818061bf53427a3e7808ef10dsewardjtypedef
213b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   struct {
214b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      SuppLocTy ty;
2152c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      Bool      name_is_simple_str; /* True if name is a string without
2162c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe                                       '?' and '*' wildcard characters. */
21719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar*    name; /* NULL for NoName and DotDotDot */
218b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   }
219b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   SuppLoc;
220b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
2214a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/* Suppressions.  Tools can get/set tool-relevant parts with functions
222c7561b931e249acf3768ead77638545b0ccaa8f1njn   declared in include/pub_tool_errormgr.h.  Extensible via the 'extra' field.
2234a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Tools can use a normal enum (with element values in the normal range
22402bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn   (0..)) for 'skind'. */
2254a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotestruct _Supp {
2264a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   struct _Supp* next;
2274a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   Int count;     // The number of times this error has been suppressed.
22819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* sname;  // The name by which the suppression is referred to.
229b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
230362441db825242200142a91bb07c4a0300b36a3ephilippe   // Index in VG_(clo_suppressions) giving filename from which suppression
231362441db825242200142a91bb07c4a0300b36a3ephilippe   // was read, and the lineno in this file where sname was read.
232362441db825242200142a91bb07c4a0300b36a3ephilippe   Int    clo_suppressions_i;
233362441db825242200142a91bb07c4a0300b36a3ephilippe   Int    sname_lineno;
234362441db825242200142a91bb07c4a0300b36a3ephilippe
235b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   // Length of 'callers'
236b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   Int n_callers;
237b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   // Array of callers, for matching stack traces.  First one (name of fn
238b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   // where err occurs) is mandatory;  rest are optional.
239b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   SuppLoc* callers;
2404a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2414a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   /* The tool-specific part */
2424a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   SuppKind skind;   // What kind of suppression.  Must use the range (0..).
24319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* string;    // String -- use is optional.  NULL by default.
2444a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   void* extra;      // Anything else -- use is optional.  NULL by default.
2454a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote};
2464a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2478e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianSuppKind VG_(get_supp_kind) ( const Supp* su )
2484a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2494a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return su->skind;
2504a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2514a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2528e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianHChar* VG_(get_supp_string) ( const Supp* su )
2534a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2544a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return su->string;
2554a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2564a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2578e3fbb5cd8276a7d07d5712bc05f9b3376d81a6aflorianvoid* VG_(get_supp_extra)  ( const Supp* su )
2584a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2594a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   return su->extra;
2604a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2614a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2624a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2634a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotevoid VG_(set_supp_kind)   ( Supp* su, SuppKind skind )
2644a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2654a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   su->skind = skind;
2664a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2674a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
26819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianvoid VG_(set_supp_string) ( Supp* su, HChar* string )
2694a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2704a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   su->string = string;
2714a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2724a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2734a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercotevoid VG_(set_supp_extra)  ( Supp* su, void* extra )
2744a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote{
2754a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote   su->extra = extra;
2764a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote}
2774a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2784a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote
2794a184908dcb3265f53aa27ccc6f6b7a447f7da49nethercote/*------------------------------------------------------------*/
280de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- Helper fns                                           ---*/
281de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
282de4a1d01951937632098a6cda45859afa587a06fsewardj
2830087c501c6356fb083c0ea12d87263aca7abf25anjn// Only show core errors if the tool wants to, we're not running with -q,
2840087c501c6356fb083c0ea12d87263aca7abf25anjn// and were not outputting XML.
2850087c501c6356fb083c0ea12d87263aca7abf25anjnBool VG_(showing_core_errors)(void)
2860087c501c6356fb083c0ea12d87263aca7abf25anjn{
2870087c501c6356fb083c0ea12d87263aca7abf25anjn   return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
2880087c501c6356fb083c0ea12d87263aca7abf25anjn}
2890087c501c6356fb083c0ea12d87263aca7abf25anjn
290738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Compare errors, to detect duplicates.
291738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
292518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool eq_Error ( VgRes res, const Error* e1, const Error* e2 )
293de4a1d01951937632098a6cda45859afa587a06fsewardj{
294810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   if (e1->ekind != e2->ekind)
295de4a1d01951937632098a6cda45859afa587a06fsewardj      return False;
296e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
297de4a1d01951937632098a6cda45859afa587a06fsewardj      return False;
298de4a1d01951937632098a6cda45859afa587a06fsewardj
299810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   switch (e1->ekind) {
300a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //(example code, see comment on CoreSuppKind above)
301a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //case ThreadErr:
302a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   vg_assert(VG_(needs).core_errors);
303a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   return <something>
304de4a1d01951937632098a6cda45859afa587a06fsewardj      default:
30551d827bcd88ce045a383ea1ca81768757df2d1fanjn         if (VG_(needs).tool_errors) {
30651d827bcd88ce045a383ea1ca81768757df2d1fanjn            return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
30751d827bcd88ce045a383ea1ca81768757df2d1fanjn         } else {
30895ec870848b73e0f90758f94f2c3e62e5c3cccefnjn            VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
309e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn                        "probably needs to be set.\n",
310a5e06c36bf9d93461bc8c4351e960888020ea1c4florian                        (UInt)e1->ekind);
311a4ca4fef8c189e861492e1e2b36b52ba3fca1725florian            VG_(core_panic)("unhandled error type");
312b581a13471f76c7f15168de4b76a3b4b453ee030sewardj         }
313de4a1d01951937632098a6cda45859afa587a06fsewardj   }
314de4a1d01951937632098a6cda45859afa587a06fsewardj}
315de4a1d01951937632098a6cda45859afa587a06fsewardj
316738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
317588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj/* Helper functions for suppression generation: print a single line of
318588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   a suppression pseudo-stack-trace, either in XML or text mode.  It's
319588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   important that the behaviour of these two functions exactly
320588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   corresponds.
321738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
322738856f99eea33d86ce91dcb1d6cd5b151e307casewardj#define ERRTXT_LEN   4096
323738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
324588adeffafa8102adcfa7a1c035ae272b35cf86dsewardjstatic void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
325de4a1d01951937632098a6cda45859afa587a06fsewardj{
32646cc04521acf2827eb33310fadc119bf2dc039e4florian   const HChar *buf;
327a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   InlIPCursor* iipc = VG_(new_IIPC)(ip);
328a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   do {
32946cc04521acf2827eb33310fadc119bf2dc039e4florian      if ( VG_(get_fnname_no_cxx_demangle) (ip, &buf, iipc) ) {
330a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(printf_xml)("    <sframe> <fun>%pS</fun> </sframe>\n", buf);
331a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
33246cc04521acf2827eb33310fadc119bf2dc039e4florian      if ( VG_(get_objname)(ip, &buf) ) {
333a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(printf_xml)("    <sframe> <obj>%pS</obj> </sframe>\n", buf);
334a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else {
335a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(printf_xml)("    <sframe> <obj>*</obj> </sframe>\n");
336a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
337a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   } while (VG_(next_IIPC)(iipc));
338a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   VG_(delete_IIPC)(iipc);
339738856f99eea33d86ce91dcb1d6cd5b151e307casewardj}
34071bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
341588adeffafa8102adcfa7a1c035ae272b35cf86dsewardjstatic void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
342588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj{
34346cc04521acf2827eb33310fadc119bf2dc039e4florian   const HChar *buf;
344588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   XArray* /* of HChar */ text = (XArray*)textV;
345a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   InlIPCursor* iipc = VG_(new_IIPC)(ip);
346a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   do {
34746cc04521acf2827eb33310fadc119bf2dc039e4florian      if ( VG_(get_fnname_no_cxx_demangle) (ip, &buf, iipc) ) {
348a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(xaprintf)(text, "   fun:%s\n", buf);
349a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
35046cc04521acf2827eb33310fadc119bf2dc039e4florian      if ( VG_(get_objname)(ip, &buf) ) {
351a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(xaprintf)(text, "   obj:%s\n", buf);
352a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else {
353a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(xaprintf)(text, "   obj:*\n");
354a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
355a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   } while (VG_(next_IIPC)(iipc));
356a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   VG_(delete_IIPC)(iipc);
357588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj}
358738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
359738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Generate a suppression for an error, either in text or XML mode.
360738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
361518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void gen_suppression(const Error* err)
362738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{
363dbb3584f591710a15a437918c0fc27e300993566florian   const HChar* name;
364588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   ExeContext* ec;
365588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   XArray* /* HChar */ text;
366588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
367588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   const HChar* dummy_name = "insert_a_suppression_name_here";
368588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
369588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   vg_assert(err);
370588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
371588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   ec = VG_(get_error_where)(err);
372588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   vg_assert(ec);
373588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
374588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   name = VG_TDICT_CALL(tool_get_error_name, err);
375588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   if (NULL == name) {
376588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(umsg)("(%s does not allow error to be suppressed)\n",
377588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                VG_(details).name);
378588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      return;
379588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   }
380738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
3817420e0a2f02a2af656d33cde3d6f46ff10e13a9btom   /* In XML mode, we also need to print the plain text version of the
3827420e0a2f02a2af656d33cde3d6f46ff10e13a9btom      suppresion in a CDATA section.  What that really means is, we
3837420e0a2f02a2af656d33cde3d6f46ff10e13a9btom      need to generate the plaintext version both in XML and text
3847420e0a2f02a2af656d33cde3d6f46ff10e13a9btom      mode.  So generate it into TEXT. */
3857420e0a2f02a2af656d33cde3d6f46ff10e13a9btom   text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
3867420e0a2f02a2af656d33cde3d6f46ff10e13a9btom                      VG_(free), sizeof(HChar) );
3877420e0a2f02a2af656d33cde3d6f46ff10e13a9btom
388588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   /* Ok.  Generate the plain text version into TEXT. */
389588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(xaprintf)(text, "{\n");
390588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(xaprintf)(text, "   <%s>\n", dummy_name);
391588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(xaprintf)(text, "   %s:%s\n", VG_(details).name, name);
392738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
3933e81b8bed1f7ab6848a83f5507487131a6f9d778florian   HChar       *xtra = NULL;
3943e81b8bed1f7ab6848a83f5507487131a6f9d778florian   SizeT       xtra_size = 0;
3953e81b8bed1f7ab6848a83f5507487131a6f9d778florian   SizeT       num_written;
396588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
3973e81b8bed1f7ab6848a83f5507487131a6f9d778florian   do {
3983e81b8bed1f7ab6848a83f5507487131a6f9d778florian      xtra_size += 256;
3993e81b8bed1f7ab6848a83f5507487131a6f9d778florian      xtra = VG_(realloc)("errormgr.gen_suppression.2", xtra,xtra_size);
4003e81b8bed1f7ab6848a83f5507487131a6f9d778florian      num_written = VG_TDICT_CALL(tool_get_extra_suppression_info,
4013e81b8bed1f7ab6848a83f5507487131a6f9d778florian                                  err, xtra, xtra_size);
4023e81b8bed1f7ab6848a83f5507487131a6f9d778florian   } while (num_written == xtra_size);  // resize buffer and retry
4033e81b8bed1f7ab6848a83f5507487131a6f9d778florian
4043e81b8bed1f7ab6848a83f5507487131a6f9d778florian   // Ensure buffer is properly terminated
4053e81b8bed1f7ab6848a83f5507487131a6f9d778florian   vg_assert(xtra[num_written] == '\0');
4063e81b8bed1f7ab6848a83f5507487131a6f9d778florian
4073e81b8bed1f7ab6848a83f5507487131a6f9d778florian   if (num_written)
408588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(xaprintf)(text, "   %s\n", xtra);
409e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
410738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   // Print stack trace elements
4112f340ebeb7aec2cac84647af2aa7239811341bf4sewardj   UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
412e2800c958044937e72eefa371c10ae47ac40e089florian   vg_assert(n_ips > 0);
413a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes   vg_assert(n_ips <= VG_DEEPEST_BACKTRACE);
414588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(apply_StackTrace)(printSuppForIp_nonXML,
415588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                         text,
416738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                         VG_(get_ExeContext_StackTrace)(ec),
4172f340ebeb7aec2cac84647af2aa7239811341bf4sewardj                         n_ips);
41871bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
419588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(xaprintf)(text, "}\n");
420588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   // zero terminate
421588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(xaprintf)(text, "%c", (HChar)0 );
422588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   // VG_(printf) of text
423588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
424588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   /* And now display it. */
425588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   if (! VG_(clo_xml) ) {
426588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
427588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      // the simple case
428588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
429588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
430738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   } else {
431588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
432588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      /* Now we have to print the XML directly.  No need to go to the
433588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj         effort of stuffing it in an XArray, since we won't need it
434588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj         again. */
435588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("  <suppression>\n");
436588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("    <sname>%s</sname>\n", dummy_name);
437b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart      VG_(printf_xml)(
438b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart                      "    <skind>%pS:%pS</skind>\n", VG_(details).name, name);
4393e81b8bed1f7ab6848a83f5507487131a6f9d778florian      if (num_written)
440b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart         VG_(printf_xml)("    <skaux>%pS</skaux>\n", xtra);
441588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
442588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      // Print stack trace elements
443588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(apply_StackTrace)(printSuppForIp_XML,
444588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                            NULL,
445588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                            VG_(get_ExeContext_StackTrace)(ec),
446588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj                            VG_(get_ExeContext_n_ips)(ec));
447588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
448588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      // And now the cdata bit
449588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      // XXX FIXME!  properly handle the case where the raw text
450588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      // itself contains "]]>", as specified in Protocol 4.
451588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("    <rawtext>\n");
452588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("<![CDATA[\n");
453de78f9ad5f55102c5162ee91c893e6c4fe5db7efsewardj      VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
454588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("]]>\n");
455588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("    </rawtext>\n");
456588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj      VG_(printf_xml)("  </suppression>\n");
457588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
458738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   }
459588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj
460588adeffafa8102adcfa7a1c035ae272b35cf86dsewardj   VG_(deleteXA)(text);
4613e81b8bed1f7ab6848a83f5507487131a6f9d778florian   VG_(free)(xtra);
462de4a1d01951937632098a6cda45859afa587a06fsewardj}
463de4a1d01951937632098a6cda45859afa587a06fsewardj
464738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
465738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Figure out if we want to perform a given action for this error,
466738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   possibly by asking the user.
467738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
4682b8059ad8e01f0928e8767ae25b9103c4ef15f18florianBool VG_(is_action_requested) ( const HChar* action, Bool* clo )
469de4a1d01951937632098a6cda45859afa587a06fsewardj{
47019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar ch, ch2;
471de4a1d01951937632098a6cda45859afa587a06fsewardj   Int res;
472de4a1d01951937632098a6cda45859afa587a06fsewardj
473738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   /* First off, we shouldn't be asking the user anything if
474738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      we're in XML mode. */
475738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   if (VG_(clo_xml))
476738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      return False; /* That's a Nein, oder Nay as they say down here in B-W */
477738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
47843c799ed4de307bf00b2467b9b63e583894a030bnjn   if (*clo == False)
479de4a1d01951937632098a6cda45859afa587a06fsewardj      return False;
480de4a1d01951937632098a6cda45859afa587a06fsewardj
481738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(umsg)("\n");
482de4a1d01951937632098a6cda45859afa587a06fsewardj
483de4a1d01951937632098a6cda45859afa587a06fsewardj  again:
484de4a1d01951937632098a6cda45859afa587a06fsewardj   VG_(printf)(
485de4a1d01951937632098a6cda45859afa587a06fsewardj      "==%d== "
48643c799ed4de307bf00b2467b9b63e583894a030bnjn      "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",
48743c799ed4de307bf00b2467b9b63e583894a030bnjn      VG_(getpid)(), action
488de4a1d01951937632098a6cda45859afa587a06fsewardj   );
489de4a1d01951937632098a6cda45859afa587a06fsewardj
4906024b21f0effb97e454d312f59698be2ef5db043sewardj   res = VG_(read)(VG_(clo_input_fd), &ch, 1);
491de4a1d01951937632098a6cda45859afa587a06fsewardj   if (res != 1) goto ioerror;
492de4a1d01951937632098a6cda45859afa587a06fsewardj   /* res == 1 */
493de4a1d01951937632098a6cda45859afa587a06fsewardj   if (ch == '\n') return False;
494de4a1d01951937632098a6cda45859afa587a06fsewardj   if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y'
495de4a1d01951937632098a6cda45859afa587a06fsewardj      && ch != 'C' && ch != 'c') goto again;
496de4a1d01951937632098a6cda45859afa587a06fsewardj
4976024b21f0effb97e454d312f59698be2ef5db043sewardj   res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
498de4a1d01951937632098a6cda45859afa587a06fsewardj   if (res != 1) goto ioerror;
499de4a1d01951937632098a6cda45859afa587a06fsewardj   if (ch2 != '\n') goto again;
500de4a1d01951937632098a6cda45859afa587a06fsewardj
50143c799ed4de307bf00b2467b9b63e583894a030bnjn   /* No, don't want to do action. */
502de4a1d01951937632098a6cda45859afa587a06fsewardj   if (ch == 'n' || ch == 'N') return False;
50343c799ed4de307bf00b2467b9b63e583894a030bnjn   /* Yes, want to do action. */
504de4a1d01951937632098a6cda45859afa587a06fsewardj   if (ch == 'y' || ch == 'Y') return True;
50543c799ed4de307bf00b2467b9b63e583894a030bnjn   /* No, don't want to do action, and don't ask again either. */
506de4a1d01951937632098a6cda45859afa587a06fsewardj   vg_assert(ch == 'c' || ch == 'C');
507de4a1d01951937632098a6cda45859afa587a06fsewardj
508de4a1d01951937632098a6cda45859afa587a06fsewardj  ioerror:
50943c799ed4de307bf00b2467b9b63e583894a030bnjn   *clo = False;
510de4a1d01951937632098a6cda45859afa587a06fsewardj   return False;
511de4a1d01951937632098a6cda45859afa587a06fsewardj}
512de4a1d01951937632098a6cda45859afa587a06fsewardj
513de4a1d01951937632098a6cda45859afa587a06fsewardj
514738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Do text-mode actions on error, that is, immediately after an error
515738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   is printed.  These are:
516b9749a5a1fcf2ce8dc4a145f6037821f2a4c1252florian   * possibly, call the GDB server
517738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * possibly, generate a suppression.
518738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   Note this should not be called in XML mode!
519738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
520738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic
521518850bf0da07ed3e2244e307268ae0fd80e93a8florianvoid do_actions_on_error(const Error* err, Bool allow_db_attach)
522738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{
523738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   Bool still_noisy = True;
524738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
5253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* if user wants to debug from a certain error nr, then wait for gdb/vgdb */
5263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (VG_(clo_vgdb) != Vg_VgdbNo
5273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj       && allow_db_attach
528baf69645a5d270e6662d05d74e537e9ba970f34cphilippe       && VG_(dyn_vgdb_error) <= n_errs_shown) {
5293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      VG_(umsg)("(action on error) vgdb me ... \n");
5303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      VG_(gdbserver)( err->tid );
5313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      VG_(umsg)("Continuing ...\n");
5323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
5333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
534738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   /* Or maybe we want to generate the error's suppression? */
535738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   if (VG_(clo_gen_suppressions) == 2
536738856f99eea33d86ce91dcb1d6cd5b151e307casewardj       || (VG_(clo_gen_suppressions) == 1
537738856f99eea33d86ce91dcb1d6cd5b151e307casewardj           && VG_(is_action_requested)( "Print suppression", &still_noisy ))
538738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      ) {
539738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      gen_suppression(err);
540738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   }
541738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
542738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(clo_gen_suppressions) = 0;
543738856f99eea33d86ce91dcb1d6cd5b151e307casewardj}
544738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
545738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
546738856f99eea33d86ce91dcb1d6cd5b151e307casewardj/* Prints an error.  Not entirely simple because of the differences
547738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   between XML and text mode output.
548738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
549738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   In XML mode:
550738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
551738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * calls the tool's pre-show method, so the tool can create any
552738856f99eea33d86ce91dcb1d6cd5b151e307casewardj     preamble ahead of the message, if it wants.
553738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
554738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * prints the opening tag, and the <unique> and <tid> fields
555738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
556738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * prints the tool-specific parts of the message
557738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
558738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * if suppression generation is required, a suppression
559738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
560738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * the closing tag
561738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
562738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   In text mode:
563738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
564738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * calls the tool's pre-show method, so the tool can create any
565738856f99eea33d86ce91dcb1d6cd5b151e307casewardj     preamble ahead of the message, if it wants.
566738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
567738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   * prints the tool-specific parts of the message
568738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
569d4c37445b8233a2d6e7997b113c9af2c99e5edf5philippe   * calls do_actions_on_error.  This optionally does a gdbserver call
570d4c37445b8233a2d6e7997b113c9af2c99e5edf5philippe     and optionally prints a suppression; both of these may require user input.
571738856f99eea33d86ce91dcb1d6cd5b151e307casewardj*/
572518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void pp_Error ( const Error* err, Bool allow_db_attach, Bool xml )
573738856f99eea33d86ce91dcb1d6cd5b151e307casewardj{
574738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   /* If this fails, you probably specified your tool's method
575738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      dictionary incorrectly. */
576738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   vg_assert(VG_(needs).tool_errors);
577738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
5783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (xml) {
579738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
580738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* Ensure that suppression generation is either completely
581738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         enabled or completely disabled; either way, we won't require
582738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         any user input.  m_main.process_cmd_line_options should
583738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         ensure the asserted condition holds. */
584738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
585738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                 || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
586738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
587738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* Pre-show it to the tool */
588738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_TDICT_CALL( tool_before_pp_Error, err );
589738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
590738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* standard preamble */
591738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("<error>\n");
592738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("  <unique>0x%x</unique>\n", err->unique);
593a5e06c36bf9d93461bc8c4351e960888020ea1c4florian      VG_(printf_xml)("  <tid>%u</tid>\n", err->tid);
594497895194ef1db90aa7f3a022777b5ccb93f426bflorian      ThreadState* tst = VG_(get_ThreadState)(err->tid);
595497895194ef1db90aa7f3a022777b5ccb93f426bflorian      if (tst->thread_name) {
596497895194ef1db90aa7f3a022777b5ccb93f426bflorian         VG_(printf_xml)("  <threadname>%s</threadname>\n", tst->thread_name);
597497895194ef1db90aa7f3a022777b5ccb93f426bflorian      }
598738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
599738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* actually print it */
600738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_TDICT_CALL( tool_pp_Error, err );
601738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
602738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      if (VG_(clo_gen_suppressions) > 0)
603738856f99eea33d86ce91dcb1d6cd5b151e307casewardj        gen_suppression(err);
604738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
605738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* postamble */
606738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("</error>\n");
607b6267bd61a3802bb2a16ef993c94bf834d0e2d2enjn      VG_(printf_xml)("\n");
608738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
609738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   } else {
610738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
6117b3d3565c1559b88c67f629bd6613c8b1a89691bphilippe      if (VG_(clo_error_markers)[0])
6127b3d3565c1559b88c67f629bd6613c8b1a89691bphilippe         VG_(umsg)("%s\n", VG_(clo_error_markers)[0]);
613738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_TDICT_CALL( tool_before_pp_Error, err );
614738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
615738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      if (VG_(tdict).tool_show_ThreadIDs_for_errors
616738856f99eea33d86ce91dcb1d6cd5b151e307casewardj          && err->tid > 0 && err->tid != last_tid_printed) {
617497895194ef1db90aa7f3a022777b5ccb93f426bflorian         ThreadState* tst = VG_(get_ThreadState)(err->tid);
618497895194ef1db90aa7f3a022777b5ccb93f426bflorian         if (tst->thread_name) {
619a5e06c36bf9d93461bc8c4351e960888020ea1c4florian            VG_(umsg)("Thread %u %s:\n", err->tid, tst->thread_name );
620497895194ef1db90aa7f3a022777b5ccb93f426bflorian         } else {
621a5e06c36bf9d93461bc8c4351e960888020ea1c4florian            VG_(umsg)("Thread %u:\n", err->tid );
622497895194ef1db90aa7f3a022777b5ccb93f426bflorian         }
623738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         last_tid_printed = err->tid;
624738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      }
625738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
626738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_TDICT_CALL( tool_pp_Error, err );
627b6267bd61a3802bb2a16ef993c94bf834d0e2d2enjn      VG_(umsg)("\n");
6287b3d3565c1559b88c67f629bd6613c8b1a89691bphilippe      if (VG_(clo_error_markers)[1])
6297b3d3565c1559b88c67f629bd6613c8b1a89691bphilippe         VG_(umsg)("%s\n", VG_(clo_error_markers)[1]);
630738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
631738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   }
632d4c37445b8233a2d6e7997b113c9af2c99e5edf5philippe
633d4c37445b8233a2d6e7997b113c9af2c99e5edf5philippe   do_actions_on_error(err, allow_db_attach);
634738856f99eea33d86ce91dcb1d6cd5b151e307casewardj}
635738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
636738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
637b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj/* Construct an error */
638738856f99eea33d86ce91dcb1d6cd5b151e307casewardjstatic
63972718649e68c7eaf3d0b8cd3deebde198b2ea84dnjnvoid construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
640e543f3024ace2925a0fb81985e9fcfc95b8c555aflorian                       const HChar* s, void* extra, ExeContext* where )
641e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
642dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   /* DO NOT MAKE unique_counter NON-STATIC */
643dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   static UInt unique_counter = 0;
644dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj
645e2800c958044937e72eefa371c10ae47ac40e089florian   vg_assert(tid < VG_N_THREADS);
64672718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn
647810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   /* Core-only parts */
648dbada27b0fe85cc1437328f0cbde0cf2cd649bd8sewardj   err->unique   = unique_counter++;
649e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   err->next     = NULL;
650e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   err->supp     = NULL;
651e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   err->count    = 1;
65272718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn   err->tid      = tid;
65343c799ed4de307bf00b2467b9b63e583894a030bnjn   if (NULL == where)
654adb102f8a53d100cf2d68a1a00bb24a4bcd2b049sewardj     err->where = VG_(record_ExeContext)( tid, 0 );
65543c799ed4de307bf00b2467b9b63e583894a030bnjn   else
65643c799ed4de307bf00b2467b9b63e583894a030bnjn      err->where = where;
6571d6c4bc38bd938c055bc57c614769cee59de4793njn
658996901a830e8e7c3fd8be8f0c675c71f2b108957nethercote   /* Tool-relevant parts */
659810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   err->ekind  = ekind;
660810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   err->addr   = a;
661810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   err->extra  = extra;
662a602261f39a83016d0f9a094449d4cceccdeef81sewardj   err->string = s;
663a602261f39a83016d0f9a094449d4cceccdeef81sewardj
664e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   /* sanity... */
66572718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn   vg_assert( tid < VG_N_THREADS );
666e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
667e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
668d153fae265b08b42e44183e2f293d6ebf6b47019sewardj
66943c799ed4de307bf00b2467b9b63e583894a030bnjn
670e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn/* Top-level entry point to the error management subsystem.
671e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   All detected errors are notified here; this routine decides if/when the
672de4a1d01951937632098a6cda45859afa587a06fsewardj   user should see the error. */
67372718649e68c7eaf3d0b8cd3deebde198b2ea84dnjnvoid VG_(maybe_record_error) ( ThreadId tid,
674c06f684badc0701961e68dbc206fbf1757f7fd68philippe                               ErrorKind ekind, Addr a,
675c06f684badc0701961e68dbc206fbf1757f7fd68philippe                               const HChar* s, void* extra )
676de4a1d01951937632098a6cda45859afa587a06fsewardj{
677810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn          Error  err;
678810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn          Error* p;
679810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn          Error* p_prev;
68043c799ed4de307bf00b2467b9b63e583894a030bnjn          UInt   extra_size;
681695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn          VgRes  exe_res          = Vg_MedRes;
682695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   static Bool   stopping_message = False;
683695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   static Bool   slowdown_message = False;
684de4a1d01951937632098a6cda45859afa587a06fsewardj
68514319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
68614319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn      been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
687f2537be75c230ae083d859424f941b45ddbf302fsewardj      have been found, just refuse to collect any more.  This stops
688f2537be75c230ae083d859424f941b45ddbf302fsewardj      the burden of the error-management system becoming excessive in
689f2537be75c230ae083d859424f941b45ddbf302fsewardj      extremely buggy programs, although it does make it pretty
690f2537be75c230ae083d859424f941b45ddbf302fsewardj      pointless to continue the Valgrind run after this point. */
6912e432901e2eb0ae45bd71224f63696ae27f86d19sewardj   if (VG_(clo_error_limit)
692695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn       && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
6938a0517290410d5befa62674f85b1a3799920e2b9sewardj           || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
6948a0517290410d5befa62674f85b1a3799920e2b9sewardj       && !VG_(clo_xml)) {
695de4a1d01951937632098a6cda45859afa587a06fsewardj      if (!stopping_message) {
696738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("\n");
697f2537be75c230ae083d859424f941b45ddbf302fsewardj
698695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn	 if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
699738856f99eea33d86ce91dcb1d6cd5b151e307casewardj            VG_(umsg)(
700f2537be75c230ae083d859424f941b45ddbf302fsewardj               "More than %d different errors detected.  "
701738856f99eea33d86ce91dcb1d6cd5b151e307casewardj               "I'm not reporting any more.\n",
70214319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn               M_COLLECT_NO_ERRORS_AFTER_SHOWN );
703f2537be75c230ae083d859424f941b45ddbf302fsewardj         } else {
704738856f99eea33d86ce91dcb1d6cd5b151e307casewardj            VG_(umsg)(
705f2537be75c230ae083d859424f941b45ddbf302fsewardj               "More than %d total errors detected.  "
706738856f99eea33d86ce91dcb1d6cd5b151e307casewardj               "I'm not reporting any more.\n",
70714319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn               M_COLLECT_NO_ERRORS_AFTER_FOUND );
708f2537be75c230ae083d859424f941b45ddbf302fsewardj	 }
709f2537be75c230ae083d859424f941b45ddbf302fsewardj
710738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("Final error counts will be inaccurate.  "
711738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "Go fix your program!\n");
712738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("Rerun with --error-limit=no to disable "
713738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "this cutoff.  Note\n");
714738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("that errors may occur in your program without "
715738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "prior warning from\n");
716738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("Valgrind, because errors are no longer "
717738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "being displayed.\n");
718738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("\n");
719de4a1d01951937632098a6cda45859afa587a06fsewardj         stopping_message = True;
720de4a1d01951937632098a6cda45859afa587a06fsewardj      }
721de4a1d01951937632098a6cda45859afa587a06fsewardj      return;
722de4a1d01951937632098a6cda45859afa587a06fsewardj   }
723de4a1d01951937632098a6cda45859afa587a06fsewardj
724dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   /* Ignore it if error acquisition is disabled for this thread. */
725dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   { ThreadState* tst = VG_(get_ThreadState)(tid);
726dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj     if (tst->err_disablement_level > 0)
727dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj        return;
728dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   }
729dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
73014319cc921e0a54b5ad80abc4c04ea7ed5eccb0dnjn   /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
731de4a1d01951937632098a6cda45859afa587a06fsewardj      been found, be much more conservative about collecting new
732de4a1d01951937632098a6cda45859afa587a06fsewardj      ones. */
7338a0517290410d5befa62674f85b1a3799920e2b9sewardj   if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
7348a0517290410d5befa62674f85b1a3799920e2b9sewardj       && !VG_(clo_xml)) {
735e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      exe_res = Vg_LowRes;
736de4a1d01951937632098a6cda45859afa587a06fsewardj      if (!slowdown_message) {
737738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("\n");
738738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("More than %d errors detected.  Subsequent errors\n",
739738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   M_COLLECT_ERRORS_SLOWLY_AFTER);
740738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(umsg)("will still be recorded, but in less "
741738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "detail than before.\n");
742de4a1d01951937632098a6cda45859afa587a06fsewardj         slowdown_message = True;
743de4a1d01951937632098a6cda45859afa587a06fsewardj      }
744de4a1d01951937632098a6cda45859afa587a06fsewardj   }
745de4a1d01951937632098a6cda45859afa587a06fsewardj
746e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   /* Build ourselves the error */
74772718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn   construct_error ( &err, tid, ekind, a, s, extra, NULL );
748de4a1d01951937632098a6cda45859afa587a06fsewardj
749de4a1d01951937632098a6cda45859afa587a06fsewardj   /* First, see if we've got an error record matching this one. */
7508a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   em_errlist_searches++;
7518a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   p       = errors;
7528a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   p_prev  = NULL;
753de4a1d01951937632098a6cda45859afa587a06fsewardj   while (p != NULL) {
7548a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      em_errlist_cmps++;
755810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn      if (eq_Error(exe_res, p, &err)) {
756de4a1d01951937632098a6cda45859afa587a06fsewardj         /* Found it. */
757de4a1d01951937632098a6cda45859afa587a06fsewardj         p->count++;
758de4a1d01951937632098a6cda45859afa587a06fsewardj	 if (p->supp != NULL) {
759de4a1d01951937632098a6cda45859afa587a06fsewardj            /* Deal correctly with suppressed errors. */
760de4a1d01951937632098a6cda45859afa587a06fsewardj            p->supp->count++;
761f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote            n_errs_suppressed++;
762de4a1d01951937632098a6cda45859afa587a06fsewardj         } else {
763f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote            n_errs_found++;
764de4a1d01951937632098a6cda45859afa587a06fsewardj         }
765de4a1d01951937632098a6cda45859afa587a06fsewardj
766de4a1d01951937632098a6cda45859afa587a06fsewardj         /* Move p to the front of the list so that future searches
7673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            for it are faster. It also allows to print the last
7683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            error (see VG_(show_last_error). */
769de4a1d01951937632098a6cda45859afa587a06fsewardj         if (p_prev != NULL) {
770de4a1d01951937632098a6cda45859afa587a06fsewardj            vg_assert(p_prev->next == p);
771695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn            p_prev->next = p->next;
772695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn            p->next      = errors;
773695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn            errors       = p;
774de4a1d01951937632098a6cda45859afa587a06fsewardj	 }
7757ebf7c34ea2482482fa2d8432eb404b8083009b0sewardj
776de4a1d01951937632098a6cda45859afa587a06fsewardj         return;
777de4a1d01951937632098a6cda45859afa587a06fsewardj      }
778de4a1d01951937632098a6cda45859afa587a06fsewardj      p_prev = p;
779de4a1d01951937632098a6cda45859afa587a06fsewardj      p      = p->next;
780de4a1d01951937632098a6cda45859afa587a06fsewardj   }
781de4a1d01951937632098a6cda45859afa587a06fsewardj
782de4a1d01951937632098a6cda45859afa587a06fsewardj   /* Didn't see it.  Copy and add. */
783de4a1d01951937632098a6cda45859afa587a06fsewardj
78443c799ed4de307bf00b2467b9b63e583894a030bnjn   /* OK, we're really going to collect it.  The context is on the stack and
78543c799ed4de307bf00b2467b9b63e583894a030bnjn      will disappear shortly, so we must copy it.  First do the main
78602bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn      (non-'extra') part.
787e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
78802bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn      Then VG_(tdict).tool_update_extra can update the 'extra' part.  This
78951d827bcd88ce045a383ea1ca81768757df2d1fanjn      is for when there are more details to fill in which take time to work
79051d827bcd88ce045a383ea1ca81768757df2d1fanjn      out but don't affect our earlier decision to include the error -- by
791e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      postponing those details until now, we avoid the extra work in the
792810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn      case where we ignore the error.  Ugly.
79343c799ed4de307bf00b2467b9b63e583894a030bnjn
79402bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn      Then, if there is an 'extra' part, copy it too, using the size that
79551d827bcd88ce045a383ea1ca81768757df2d1fanjn      VG_(tdict).tool_update_extra returned.  Also allow for people using
79651d827bcd88ce045a383ea1ca81768757df2d1fanjn      the void* extra field for a scalar value like an integer.
79743c799ed4de307bf00b2467b9b63e583894a030bnjn   */
79843c799ed4de307bf00b2467b9b63e583894a030bnjn
79943c799ed4de307bf00b2467b9b63e583894a030bnjn   /* copy main part */
800a2968ccb86332489ac050bc194da7e3066770bc5florian   p = VG_(malloc)("errormgr.mre.1", sizeof(Error));
801e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   *p = err;
80243c799ed4de307bf00b2467b9b63e583894a030bnjn
80302bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn   /* update 'extra' */
804b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   switch (ekind) {
805a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //(example code, see comment on CoreSuppKind above)
806a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //case ThreadErr:
807a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   vg_assert(VG_(needs).core_errors);
808a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   extra_size = <something>
809a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   break;
810b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      default:
811b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         vg_assert(VG_(needs).tool_errors);
81251d827bcd88ce045a383ea1ca81768757df2d1fanjn         extra_size = VG_TDICT_CALL(tool_update_extra, p);
813b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         break;
814b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   }
81543c799ed4de307bf00b2467b9b63e583894a030bnjn
816c06f684badc0701961e68dbc206fbf1757f7fd68philippe   /* copy the error string, if there is one.
817c06f684badc0701961e68dbc206fbf1757f7fd68philippe      note: if we would have many errors with big strings, using a
818c06f684badc0701961e68dbc206fbf1757f7fd68philippe      DedupPoolAlloc for these strings will avoid duplicating
819c06f684badc0701961e68dbc206fbf1757f7fd68philippe      such string in each error using it. */
820c06f684badc0701961e68dbc206fbf1757f7fd68philippe   if (NULL != p->string) {
82177eb20b3865e7b17c7695c7e7a526b52935f593eflorian      p->string = VG_(strdup)("errormgr.mre.2", p->string);
822c06f684badc0701961e68dbc206fbf1757f7fd68philippe   }
823c06f684badc0701961e68dbc206fbf1757f7fd68philippe
82402bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn   /* copy block pointed to by 'extra', if there is one */
825b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj   if (NULL != p->extra && 0 != extra_size) {
826c06f684badc0701961e68dbc206fbf1757f7fd68philippe      void* new_extra = VG_(malloc)("errormgr.mre.3", extra_size);
827b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      VG_(memcpy)(new_extra, p->extra, extra_size);
828b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      p->extra = new_extra;
82943c799ed4de307bf00b2467b9b63e583894a030bnjn   }
83043c799ed4de307bf00b2467b9b63e583894a030bnjn
831695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   p->next = errors;
832e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   p->supp = is_suppressible_error(&err);
833695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   errors  = p;
834de4a1d01951937632098a6cda45859afa587a06fsewardj   if (p->supp == NULL) {
835baf69645a5d270e6662d05d74e537e9ba970f34cphilippe      /* update stats */
836606a4aeacb004873d2839467e2ad0ab3aabc8c27njn      n_err_contexts++;
837f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote      n_errs_found++;
838baf69645a5d270e6662d05d74e537e9ba970f34cphilippe      n_errs_shown++;
839738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      /* Actually show the error; more complex than you might think. */
8403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
841de4a1d01951937632098a6cda45859afa587a06fsewardj   } else {
842606a4aeacb004873d2839467e2ad0ab3aabc8c27njn      n_supp_contexts++;
843f2b1148e1dfea70023f57f81b6ced770f3c22231nethercote      n_errs_suppressed++;
844de4a1d01951937632098a6cda45859afa587a06fsewardj      p->supp->count++;
845de4a1d01951937632098a6cda45859afa587a06fsewardj   }
846de4a1d01951937632098a6cda45859afa587a06fsewardj}
847de4a1d01951937632098a6cda45859afa587a06fsewardj
84843c799ed4de307bf00b2467b9b63e583894a030bnjn/* Second top-level entry point to the error management subsystem, for
8497cc9c239f785f2903b597cdb34418bed42d25331nethercote   errors that the tool wants to report immediately, eg. because they're
85043c799ed4de307bf00b2467b9b63e583894a030bnjn   guaranteed to only happen once.  This avoids all the recording and
85143c799ed4de307bf00b2467b9b63e583894a030bnjn   comparing stuff.  But they can be suppressed;  returns True if it is
85202bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn   suppressed.  Bool 'print_error' dictates whether to print the error.
85318afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn   Bool 'count_error' dictates whether to count the error in n_errs_found.
85447363aba8fa03b094195bca99fc232ce5f85605dnjn*/
855e543f3024ace2925a0fb81985e9fcfc95b8c555aflorianBool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, const HChar* s,
8563e88418f808bf2840646504481d6a5be1df16541njn                         void* extra, ExeContext* where, Bool print_error,
85718afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn                         Bool allow_db_attach, Bool count_error )
85843c799ed4de307bf00b2467b9b63e583894a030bnjn{
859fb289bc5cac4f2493c36579f7d091ce183c3fc55njn   Error err;
860fb289bc5cac4f2493c36579f7d091ce183c3fc55njn   Supp *su;
86143c799ed4de307bf00b2467b9b63e583894a030bnjn
862dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   /* Ignore it if error acquisition is disabled for this thread. */
863dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   ThreadState* tst = VG_(get_ThreadState)(tid);
864dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj   if (tst->err_disablement_level > 0)
865dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj      return False; /* ignored, not suppressed */
866dc873c08cc51930ecd35a976c1d03285f9a53b94sewardj
86743c799ed4de307bf00b2467b9b63e583894a030bnjn   /* Build ourselves the error */
86872718649e68c7eaf3d0b8cd3deebde198b2ea84dnjn   construct_error ( &err, tid, ekind, a, s, extra, where );
86943c799ed4de307bf00b2467b9b63e583894a030bnjn
87043c799ed4de307bf00b2467b9b63e583894a030bnjn   /* Unless it's suppressed, we're going to show it.  Don't need to make
87143c799ed4de307bf00b2467b9b63e583894a030bnjn      a copy, because it's only temporary anyway.
87243c799ed4de307bf00b2467b9b63e583894a030bnjn
87302bc4b8f54227320aa2b9ac4805173e0e2e3eeaenjn      Then update the 'extra' part with VG_(tdict).tool_update_extra),
87451d827bcd88ce045a383ea1ca81768757df2d1fanjn      because that can have an affect on whether it's suppressed.  Ignore
87551d827bcd88ce045a383ea1ca81768757df2d1fanjn      the size return value of VG_(tdict).tool_update_extra, because we're
876c06f684badc0701961e68dbc206fbf1757f7fd68philippe      not copying 'extra'. Similarly, 's' is also not copied. */
87751d827bcd88ce045a383ea1ca81768757df2d1fanjn   (void)VG_TDICT_CALL(tool_update_extra, &err);
87843c799ed4de307bf00b2467b9b63e583894a030bnjn
879fb289bc5cac4f2493c36579f7d091ce183c3fc55njn   su = is_suppressible_error(&err);
880fb289bc5cac4f2493c36579f7d091ce183c3fc55njn   if (NULL == su) {
881606a4aeacb004873d2839467e2ad0ab3aabc8c27njn      if (count_error) {
88218afe5d1c3dc9e4e16d3e10617d6afa4bf9fcd40njn         n_errs_found++;
883606a4aeacb004873d2839467e2ad0ab3aabc8c27njn         n_err_contexts++;
884606a4aeacb004873d2839467e2ad0ab3aabc8c27njn      }
88543c799ed4de307bf00b2467b9b63e583894a030bnjn
88643c799ed4de307bf00b2467b9b63e583894a030bnjn      if (print_error) {
887738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         /* update stats */
888fb289bc5cac4f2493c36579f7d091ce183c3fc55njn         n_errs_shown++;
889baf69645a5d270e6662d05d74e537e9ba970f34cphilippe         /* Actually show the error; more complex than you might think. */
890baf69645a5d270e6662d05d74e537e9ba970f34cphilippe         pp_Error(&err, allow_db_attach, VG_(clo_xml));
89143c799ed4de307bf00b2467b9b63e583894a030bnjn      }
89243c799ed4de307bf00b2467b9b63e583894a030bnjn      return False;
89343c799ed4de307bf00b2467b9b63e583894a030bnjn
89443c799ed4de307bf00b2467b9b63e583894a030bnjn   } else {
895663ab79fc83ace9b343723aa95e5730baab1de82njn      if (count_error) {
896663ab79fc83ace9b343723aa95e5730baab1de82njn         n_errs_suppressed++;
897663ab79fc83ace9b343723aa95e5730baab1de82njn         n_supp_contexts++;
898663ab79fc83ace9b343723aa95e5730baab1de82njn      }
899fb289bc5cac4f2493c36579f7d091ce183c3fc55njn      su->count++;
90043c799ed4de307bf00b2467b9b63e583894a030bnjn      return True;
90143c799ed4de307bf00b2467b9b63e583894a030bnjn   }
90243c799ed4de307bf00b2467b9b63e583894a030bnjn}
90343c799ed4de307bf00b2467b9b63e583894a030bnjn
904de4a1d01951937632098a6cda45859afa587a06fsewardj
905de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
906de4a1d01951937632098a6cda45859afa587a06fsewardj/*--- Exported fns                                         ---*/
907de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
908de4a1d01951937632098a6cda45859afa587a06fsewardj
90971bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj/* Show the used suppressions.  Returns False if no suppression
91071bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   got used. */
91171bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardjstatic Bool show_used_suppressions ( void )
91271bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj{
91371bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   Supp  *su;
91471bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   Bool  any_supp;
91571bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
9167c9e57c3c537a600af1d34a8abbbd14480c9e397sewardj   if (VG_(clo_xml))
917738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("<suppcounts>\n");
9187c9e57c3c537a600af1d34a8abbbd14480c9e397sewardj
91971bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   any_supp = False;
92071bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   for (su = suppressions; su != NULL; su = su->next) {
92171bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      if (su->count <= 0)
92271bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj         continue;
92371bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      if (VG_(clo_xml)) {
924b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart         VG_(printf_xml)( "  <pair>\n"
925738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                                 "    <count>%d</count>\n"
926b3af9cf0b234d0d188347d92944e04ac9c8fbcd0bart                                 "    <name>%pS</name>\n"
927738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                                 "  </pair>\n",
928738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                                 su->count, su->sname );
92971bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      } else {
9303e81b8bed1f7ab6848a83f5507487131a6f9d778florian         HChar      *xtra = NULL;
9313e81b8bed1f7ab6848a83f5507487131a6f9d778florian         Int         xtra_size = 0;
9323e81b8bed1f7ab6848a83f5507487131a6f9d778florian         SizeT       num_written;
9332d9e874b7a628ada216f09cc4f065798c65fffa4sewardj         // blank line before the first shown suppression, if any
9342d9e874b7a628ada216f09cc4f065798c65fffa4sewardj         if (!any_supp)
9352d9e874b7a628ada216f09cc4f065798c65fffa4sewardj            VG_(dmsg)("\n");
9363e81b8bed1f7ab6848a83f5507487131a6f9d778florian
9373e81b8bed1f7ab6848a83f5507487131a6f9d778florian         do {
9383e81b8bed1f7ab6848a83f5507487131a6f9d778florian            xtra_size += 256;
9393e81b8bed1f7ab6848a83f5507487131a6f9d778florian            xtra = VG_(realloc)("errormgr.sus.1", xtra, xtra_size);
9403e81b8bed1f7ab6848a83f5507487131a6f9d778florian            num_written = VG_TDICT_CALL(tool_print_extra_suppression_use,
9413e81b8bed1f7ab6848a83f5507487131a6f9d778florian                                        su, xtra, xtra_size);
9423e81b8bed1f7ab6848a83f5507487131a6f9d778florian         } while (num_written == xtra_size); // resize buffer and retry
9433e81b8bed1f7ab6848a83f5507487131a6f9d778florian
9443e81b8bed1f7ab6848a83f5507487131a6f9d778florian         // Ensure buffer is properly terminated
9453e81b8bed1f7ab6848a83f5507487131a6f9d778florian         vg_assert(xtra[num_written] == '\0');
9463e81b8bed1f7ab6848a83f5507487131a6f9d778florian
9477931627282eede4440f3f329b657c3ec68371e8aflorian         HChar *filename = *(HChar**) VG_(indexXA)(VG_(clo_suppressions),
9487931627282eede4440f3f329b657c3ec68371e8aflorian                                                   su->clo_suppressions_i);
9494e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         VG_(dmsg)("used_suppression: %6d %s %s:%d%s%s\n", su->count, su->sname,
9507931627282eede4440f3f329b657c3ec68371e8aflorian                   filename,
9514e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe                   su->sname_lineno,
9523e81b8bed1f7ab6848a83f5507487131a6f9d778florian                   num_written ? " " : "", xtra);
9533e81b8bed1f7ab6848a83f5507487131a6f9d778florian         VG_(free)(xtra);
95471bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      }
9552d9e874b7a628ada216f09cc4f065798c65fffa4sewardj      any_supp = True;
95671bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   }
95771bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
9587c9e57c3c537a600af1d34a8abbbd14480c9e397sewardj   if (VG_(clo_xml))
959738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("</suppcounts>\n");
9607c9e57c3c537a600af1d34a8abbbd14480c9e397sewardj
96171bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   return any_supp;
96271bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj}
96371bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
9649f297ca50245f24b23fada944e2f5268d313eb96sewardj/* Show all the errors that occurred, and possibly also the
9659f297ca50245f24b23fada944e2f5268d313eb96sewardj   suppressions used. */
9663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid VG_(show_all_errors) (  Int verbosity, Bool xml )
967de4a1d01951937632098a6cda45859afa587a06fsewardj{
968810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   Int    i, n_min;
969810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   Error *p, *p_min;
970810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   Bool   any_supp;
971de4a1d01951937632098a6cda45859afa587a06fsewardj
9723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (verbosity == 0)
973de4a1d01951937632098a6cda45859afa587a06fsewardj      return;
974de4a1d01951937632098a6cda45859afa587a06fsewardj
975606a4aeacb004873d2839467e2ad0ab3aabc8c27njn   /* If we're printing XML, just show the suppressions and stop. */
9763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (xml) {
97771bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      (void)show_used_suppressions();
97871bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj      return;
97971bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   }
98071bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj
98171bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   /* We only get here if not printing XML. */
982738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(umsg)("ERROR SUMMARY: "
983a5e06c36bf9d93461bc8c4351e960888020ea1c4florian             "%u errors from %u contexts (suppressed: %u from %u)\n",
984738856f99eea33d86ce91dcb1d6cd5b151e307casewardj             n_errs_found, n_err_contexts,
985738856f99eea33d86ce91dcb1d6cd5b151e307casewardj             n_errs_suppressed, n_supp_contexts );
986de4a1d01951937632098a6cda45859afa587a06fsewardj
9873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (verbosity <= 1)
988de4a1d01951937632098a6cda45859afa587a06fsewardj      return;
989de4a1d01951937632098a6cda45859afa587a06fsewardj
9902d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   // We do the following only at -v or above, and only in non-XML
9912d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   // mode
9922d9e874b7a628ada216f09cc4f065798c65fffa4sewardj
9933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Print the contexts in order of increasing error count.
9943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      Once an error is shown, we add a huge value to its count to filter it
995362441db825242200142a91bb07c4a0300b36a3ephilippe      out.
996362441db825242200142a91bb07c4a0300b36a3ephilippe      After having shown all errors, we reset count to the original value. */
997de4a1d01951937632098a6cda45859afa587a06fsewardj   for (i = 0; i < n_err_contexts; i++) {
998de4a1d01951937632098a6cda45859afa587a06fsewardj      n_min = (1 << 30) - 1;
999de4a1d01951937632098a6cda45859afa587a06fsewardj      p_min = NULL;
1000695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn      for (p = errors; p != NULL; p = p->next) {
1001de4a1d01951937632098a6cda45859afa587a06fsewardj         if (p->supp != NULL) continue;
1002de4a1d01951937632098a6cda45859afa587a06fsewardj         if (p->count < n_min) {
1003de4a1d01951937632098a6cda45859afa587a06fsewardj            n_min = p->count;
1004de4a1d01951937632098a6cda45859afa587a06fsewardj            p_min = p;
1005de4a1d01951937632098a6cda45859afa587a06fsewardj         }
1006de4a1d01951937632098a6cda45859afa587a06fsewardj      }
1007663ab79fc83ace9b343723aa95e5730baab1de82njn      // XXX: this isn't right.  See bug 203651.
1008a4ca4fef8c189e861492e1e2b36b52ba3fca1725florian      if (p_min == NULL) continue; //VG_(core_panic)("show_all_errors()");
1009de4a1d01951937632098a6cda45859afa587a06fsewardj
1010738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(umsg)("\n");
1011a5e06c36bf9d93461bc8c4351e960888020ea1c4florian      VG_(umsg)("%d errors in context %d of %u:\n",
1012738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                p_min->count, i+1, n_err_contexts);
10133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );
1014738856f99eea33d86ce91dcb1d6cd5b151e307casewardj
1015738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      // We're not printing XML -- we'd have exited above if so.
10163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vg_assert(! xml);
1017de4a1d01951937632098a6cda45859afa587a06fsewardj
1018de4a1d01951937632098a6cda45859afa587a06fsewardj      if ((i+1 == VG_(clo_dump_error))) {
10197cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj         StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
1020fa8ec113ecff891bdefb13dd361b40a503a992f8sewardj         VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
1021394213a582d2c388eea41c142b4455fb8c2c48a4njn                          ips[0], /*debugging*/True, 0xFE/*verbosity*/,
10220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                          /*bbs_done*/0,
10230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                          /*allow redir?*/True);
1024de4a1d01951937632098a6cda45859afa587a06fsewardj      }
1025de4a1d01951937632098a6cda45859afa587a06fsewardj
10263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      p_min->count = p_min->count + (1 << 30);
1027de4a1d01951937632098a6cda45859afa587a06fsewardj   }
1028de4a1d01951937632098a6cda45859afa587a06fsewardj
10293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* reset the counts, otherwise a 2nd call does not show anything anymore */
10303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (p = errors; p != NULL; p = p->next) {
10313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (p->count >= (1 << 30))
10323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         p->count = p->count - (1 << 30);
10333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
103671bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardj   any_supp = show_used_suppressions();
1037de4a1d01951937632098a6cda45859afa587a06fsewardj
10382d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   if (any_supp)
1039738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(umsg)("\n");
10402d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   // reprint this, so users don't have to scroll way up to find
10412d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   // the first printing
10422d9e874b7a628ada216f09cc4f065798c65fffa4sewardj   VG_(umsg)("ERROR SUMMARY: "
1043a5e06c36bf9d93461bc8c4351e960888020ea1c4florian             "%u errors from %u contexts (suppressed: %u from %u)\n",
10442d9e874b7a628ada216f09cc4f065798c65fffa4sewardj             n_errs_found, n_err_contexts, n_errs_suppressed,
10452d9e874b7a628ada216f09cc4f065798c65fffa4sewardj             n_supp_contexts );
1046de4a1d01951937632098a6cda45859afa587a06fsewardj}
1047de4a1d01951937632098a6cda45859afa587a06fsewardj
10483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid VG_(show_last_error) ( void )
10493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
10503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (n_err_contexts == 0) {
10513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      VG_(umsg)("No errors yet\n");
10523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return;
10533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pp_Error( errors, False/*allow_db_attach*/, False/*xml*/ );
10563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
10573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10589f297ca50245f24b23fada944e2f5268d313eb96sewardj
10599f297ca50245f24b23fada944e2f5268d313eb96sewardj/* Show occurrence counts of all errors, in XML form. */
10609f297ca50245f24b23fada944e2f5268d313eb96sewardjvoid VG_(show_error_counts_as_XML) ( void )
10619f297ca50245f24b23fada944e2f5268d313eb96sewardj{
10629f297ca50245f24b23fada944e2f5268d313eb96sewardj   Error* err;
1063738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(printf_xml)("<errorcounts>\n");
10649f297ca50245f24b23fada944e2f5268d313eb96sewardj   for (err = errors; err != NULL; err = err->next) {
10659f297ca50245f24b23fada944e2f5268d313eb96sewardj      if (err->supp != NULL)
10669f297ca50245f24b23fada944e2f5268d313eb96sewardj         continue;
10679f297ca50245f24b23fada944e2f5268d313eb96sewardj      if (err->count <= 0)
10689f297ca50245f24b23fada944e2f5268d313eb96sewardj         continue;
1069738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("  <pair>\n");
1070738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("    <count>%d</count>\n", err->count);
1071738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("    <unique>0x%x</unique>\n", err->unique);
1072738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(printf_xml)("  </pair>\n");
10739f297ca50245f24b23fada944e2f5268d313eb96sewardj   }
1074738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(printf_xml)("</errorcounts>\n");
1075b6267bd61a3802bb2a16ef993c94bf834d0e2d2enjn   VG_(printf_xml)("\n");
10769f297ca50245f24b23fada944e2f5268d313eb96sewardj}
10779f297ca50245f24b23fada944e2f5268d313eb96sewardj
10789f297ca50245f24b23fada944e2f5268d313eb96sewardj
1079de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
1080d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--- Suppression parsing                                  ---*/
1081de4a1d01951937632098a6cda45859afa587a06fsewardj/*------------------------------------------------------------*/
1082de4a1d01951937632098a6cda45859afa587a06fsewardj
10838a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Get the next char from fd into *out_buf.  Returns 1 if success,
10848a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   0 if eof or < 0 if error. */
10858a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
108619f91bbaedb4caef8a60ce94b0f507193cc0bc10florianstatic Int get_char ( Int fd, HChar* out_buf )
10878a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj{
10888a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   Int r;
108919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   static HChar buf[256];
10908a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   static Int buf_size = 0;
10918a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   static Int buf_used = 0;
10923130eab8c67d0c720cb1a86906cc057daa9700ccflorian   vg_assert(buf_size >= 0 && buf_size <= sizeof buf);
10938a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   vg_assert(buf_used >= 0 && buf_used <= buf_size);
10948a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   if (buf_used == buf_size) {
10953130eab8c67d0c720cb1a86906cc057daa9700ccflorian      r = VG_(read)(fd, buf, sizeof buf);
10968a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      if (r < 0) return r; /* read failed */
10973130eab8c67d0c720cb1a86906cc057daa9700ccflorian      vg_assert(r >= 0 && r <= sizeof buf);
10988a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      buf_size = r;
10998a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      buf_used = 0;
11008a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   }
11018a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   if (buf_size == 0)
11028a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj     return 0; /* eof */
11033130eab8c67d0c720cb1a86906cc057daa9700ccflorian   vg_assert(buf_size >= 0 && buf_size <= sizeof buf);
11048a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   vg_assert(buf_used >= 0 && buf_used < buf_size);
11058a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   *out_buf = buf[buf_used];
11068a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   buf_used++;
11078a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   return 1;
11088a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj}
11098a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
11102193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe// Get a non blank non comment line.
11112193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe// Returns True if eof.
11122193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippestatic Bool get_nbnc_line ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
1113de4a1d01951937632098a6cda45859afa587a06fsewardj{
111419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* buf  = *bufpp;
111535db56c19847654f22b62da059083d41ff4258c5njn   SizeT nBuf = *nBufp;
111619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar  ch;
111735db56c19847654f22b62da059083d41ff4258c5njn   Int   n, i;
1118362441db825242200142a91bb07c4a0300b36a3ephilippe
1119362441db825242200142a91bb07c4a0300b36a3ephilippe   vg_assert(lineno); // lineno needed to correctly track line numbers.
1120362441db825242200142a91bb07c4a0300b36a3ephilippe
1121de4a1d01951937632098a6cda45859afa587a06fsewardj   while (True) {
11222193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      buf[0] = 0;
1123de4a1d01951937632098a6cda45859afa587a06fsewardj      /* First, read until a non-blank char appears. */
1124de4a1d01951937632098a6cda45859afa587a06fsewardj      while (True) {
11258a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         n = get_char(fd, &ch);
11260c0f32a31a69dbec390176988551a50ccee30f75njn         if (n == 1 && !VG_(isspace)(ch)) break;
1127190bd525e890352277188025dbc2d7935b431499florian         if (n == 1 && ch == '\n')
1128050eec553cdcb2ebeaefbb267aeb0828be7121e5bart            (*lineno)++;
11298a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         if (n <= 0) return True;
1130de4a1d01951937632098a6cda45859afa587a06fsewardj      }
1131de4a1d01951937632098a6cda45859afa587a06fsewardj
1132de4a1d01951937632098a6cda45859afa587a06fsewardj      /* Now, read the line into buf. */
1133de4a1d01951937632098a6cda45859afa587a06fsewardj      i = 0;
1134de4a1d01951937632098a6cda45859afa587a06fsewardj      buf[i++] = ch; buf[i] = 0;
1135de4a1d01951937632098a6cda45859afa587a06fsewardj      while (True) {
11368a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         n = get_char(fd, &ch);
11378a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         if (n <= 0) return False; /* the next call will return True */
1138190bd525e890352277188025dbc2d7935b431499florian         if (ch == '\n')
1139050eec553cdcb2ebeaefbb267aeb0828be7121e5bart            (*lineno)++;
1140de4a1d01951937632098a6cda45859afa587a06fsewardj         if (ch == '\n') break;
114135db56c19847654f22b62da059083d41ff4258c5njn         if (i > 0 && i == nBuf-1) {
114235db56c19847654f22b62da059083d41ff4258c5njn            *nBufp = nBuf = nBuf * 2;
114335db56c19847654f22b62da059083d41ff4258c5njn            #define RIDICULOUS   100000
114435db56c19847654f22b62da059083d41ff4258c5njn            vg_assert2(nBuf < RIDICULOUS,  // Just a sanity check, really.
114535db56c19847654f22b62da059083d41ff4258c5njn               "VG_(get_line): line longer than %d chars, aborting\n",
114635db56c19847654f22b62da059083d41ff4258c5njn               RIDICULOUS);
114735db56c19847654f22b62da059083d41ff4258c5njn            *bufpp = buf = VG_(realloc)("errormgr.get_line.1", buf, nBuf);
114835db56c19847654f22b62da059083d41ff4258c5njn         }
1149de4a1d01951937632098a6cda45859afa587a06fsewardj         buf[i++] = ch; buf[i] = 0;
1150de4a1d01951937632098a6cda45859afa587a06fsewardj      }
11510c0f32a31a69dbec390176988551a50ccee30f75njn      while (i > 1 && VG_(isspace)(buf[i-1])) {
1152de4a1d01951937632098a6cda45859afa587a06fsewardj         i--; buf[i] = 0;
1153de4a1d01951937632098a6cda45859afa587a06fsewardj      };
1154de4a1d01951937632098a6cda45859afa587a06fsewardj
1155362441db825242200142a91bb07c4a0300b36a3ephilippe      // VG_(printf)("The line *%p %d is '%s'\n", lineno, *lineno, buf);
1156de4a1d01951937632098a6cda45859afa587a06fsewardj      /* Ok, we have a line.  If a non-comment line, return.
1157de4a1d01951937632098a6cda45859afa587a06fsewardj         If a comment line, start all over again. */
1158de4a1d01951937632098a6cda45859afa587a06fsewardj      if (buf[0] != '#') return False;
1159de4a1d01951937632098a6cda45859afa587a06fsewardj   }
1160de4a1d01951937632098a6cda45859afa587a06fsewardj}
1161de4a1d01951937632098a6cda45859afa587a06fsewardj
11622193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe// True if buf starts with fun: or obj: or is ...
1163518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool is_location_line (const HChar* buf)
11642193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe{
11652193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   return VG_(strncmp)(buf, "fun:", 4) == 0
11662193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      || VG_(strncmp)(buf, "obj:", 4) == 0
11672193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      || VG_(strcmp)(buf, "...") == 0;
11682193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe}
11692193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
11702193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippeBool VG_(get_line) ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
11712193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe{
11722193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   Bool eof = get_nbnc_line (fd, bufpp, nBufp, lineno);
11732193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
11742193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   if (eof)
11752193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      return True;
11762193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
11772193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   if (is_location_line(*bufpp))
11782193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      return True; // Not a extra suppr line
11792193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   else
1180362441db825242200142a91bb07c4a0300b36a3ephilippe      return False; // A suppression extra line
11812193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe}
1182de4a1d01951937632098a6cda45859afa587a06fsewardj
11832c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe/* True if s contains no wildcard (?, *) characters. */
118419f91bbaedb4caef8a60ce94b0f507193cc0bc10florianstatic Bool is_simple_str (const HChar *s)
11852c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe{
11862c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe   while (*s) {
11872c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      if (*s == '?' || *s == '*')
11882c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe         return False;
11892c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      s++;
11902c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe   }
11912c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe   return True;
11922c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe}
11932c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe
11947d69fd986190ebe179ca151f7c629e17a967fbfbphilippe/* buf contains the raw name of a caller, supposedly either
1195de4a1d01951937632098a6cda45859afa587a06fsewardj       fun:some_function_name   or
11967d69fd986190ebe179ca151f7c629e17a967fbfbphilippe       obj:some_object_name     or
11977d69fd986190ebe179ca151f7c629e17a967fbfbphilippe       ...
11987d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   Set p->ty and p->name accordingly.
11997d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   p->name is allocated and set to the string
12007d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   after the descriptor (fun: or obj:) part.
1201de4a1d01951937632098a6cda45859afa587a06fsewardj   Returns False if failed.
1202de4a1d01951937632098a6cda45859afa587a06fsewardj*/
1203518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool setLocationTy ( SuppLoc* p, const HChar *buf )
1204de4a1d01951937632098a6cda45859afa587a06fsewardj{
12057d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   if (VG_(strncmp)(buf, "fun:", 4) == 0) {
120677eb20b3865e7b17c7695c7e7a526b52935f593eflorian      p->name = VG_(strdup)("errormgr.sLTy.1", buf+4);
12072c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      p->name_is_simple_str = is_simple_str (p->name);
1208b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      p->ty = FunName;
1209de4a1d01951937632098a6cda45859afa587a06fsewardj      return True;
1210de4a1d01951937632098a6cda45859afa587a06fsewardj   }
12117d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   if (VG_(strncmp)(buf, "obj:", 4) == 0) {
121277eb20b3865e7b17c7695c7e7a526b52935f593eflorian      p->name = VG_(strdup)("errormgr.sLTy.2", buf+4);
12132c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      p->name_is_simple_str = is_simple_str (p->name);
1214b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      p->ty = ObjName;
1215de4a1d01951937632098a6cda45859afa587a06fsewardj      return True;
1216de4a1d01951937632098a6cda45859afa587a06fsewardj   }
12177d69fd986190ebe179ca151f7c629e17a967fbfbphilippe   if (VG_(strcmp)(buf, "...") == 0) {
12185e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      p->name = NULL;
12192c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      p->name_is_simple_str = False;
12205e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      p->ty = DotDotDot;
12215e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      return True;
12225e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj   }
12235e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj   VG_(printf)("location should be \"...\", or should start "
12245e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj               "with \"fun:\" or \"obj:\"\n");
1225de4a1d01951937632098a6cda45859afa587a06fsewardj   return False;
1226de4a1d01951937632098a6cda45859afa587a06fsewardj}
1227de4a1d01951937632098a6cda45859afa587a06fsewardj
1228de4a1d01951937632098a6cda45859afa587a06fsewardj
12297cc9c239f785f2903b597cdb34418bed42d25331nethercote/* Look for "tool" in a string like "tool1,tool2,tool3" */
1230518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool tool_name_present(const HChar *name, const HChar *names)
123111cc9257368fda337b88ef699f9383a096d6e1a9njn{
123211cc9257368fda337b88ef699f9383a096d6e1a9njn   Bool  found;
123319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar *s = NULL;   /* Shut gcc up */
123411cc9257368fda337b88ef699f9383a096d6e1a9njn   Int   len = VG_(strlen)(name);
123511cc9257368fda337b88ef699f9383a096d6e1a9njn
123611cc9257368fda337b88ef699f9383a096d6e1a9njn   found = (NULL != (s = VG_(strstr)(names, name)) &&
123711cc9257368fda337b88ef699f9383a096d6e1a9njn            (s        == names || *(s-1)   == ',') &&
123811cc9257368fda337b88ef699f9383a096d6e1a9njn            (*(s+len) == ','   || *(s+len) == '\0')
123911cc9257368fda337b88ef699f9383a096d6e1a9njn           );
124011cc9257368fda337b88ef699f9383a096d6e1a9njn
124111cc9257368fda337b88ef699f9383a096d6e1a9njn   return found;
124211cc9257368fda337b88ef699f9383a096d6e1a9njn}
124311cc9257368fda337b88ef699f9383a096d6e1a9njn
1244362441db825242200142a91bb07c4a0300b36a3ephilippe/* Read suppressions from the file specified in
1245362441db825242200142a91bb07c4a0300b36a3ephilippe   VG_(clo_suppressions)[clo_suppressions_i]
1246de4a1d01951937632098a6cda45859afa587a06fsewardj   and place them in the suppressions list.  If there's any difficulty
1247de4a1d01951937632098a6cda45859afa587a06fsewardj   doing this, just give up -- there's no point in trying to recover.
1248de4a1d01951937632098a6cda45859afa587a06fsewardj*/
1249362441db825242200142a91bb07c4a0300b36a3ephilippestatic void load_one_suppressions_file ( Int clo_suppressions_i )
1250de4a1d01951937632098a6cda45859afa587a06fsewardj{
12517931627282eede4440f3f329b657c3ec68371e8aflorian   const HChar* filename = *(HChar**) VG_(indexXA)(VG_(clo_suppressions),
12527931627282eede4440f3f329b657c3ec68371e8aflorian                                                   clo_suppressions_i);
12539264559eba4aa5d397a278b4e1a50c03de30693fsewardj   SysRes sres;
12545e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj   Int    fd, i, j, lineno = 0;
12552193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe   Bool   got_a_location_line_read_by_tool;
12569264559eba4aa5d397a278b4e1a50c03de30693fsewardj   Bool   eof;
125735db56c19847654f22b62da059083d41ff4258c5njn   SizeT  nBuf = 200;
125819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* buf = VG_(malloc)("errormgr.losf.1", nBuf);
125919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* tool_names;
126019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* supp_name;
12612b8059ad8e01f0928e8767ae25b9103c4ef15f18florian   const HChar* err_str = NULL;
1262a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes   SuppLoc tmp_callers[VG_DEEPEST_BACKTRACE];
1263c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn
1264cc37d2eea056805a5033e608dd557be84fadcd16njn   // Check it's not a directory.
1265cc37d2eea056805a5033e608dd557be84fadcd16njn   if (VG_(is_dir)( filename )) {
1266cc37d2eea056805a5033e608dd557be84fadcd16njn      if (VG_(clo_xml))
126709361bf997371238c2090cf5bacbe7f1eff90b44sewardj         VG_(printf_xml)("</valgrindoutput>\n");
1268738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
1269cc37d2eea056805a5033e608dd557be84fadcd16njn      VG_(exit)(1);
1270cc37d2eea056805a5033e608dd557be84fadcd16njn   }
1271cc37d2eea056805a5033e608dd557be84fadcd16njn
1272cc37d2eea056805a5033e608dd557be84fadcd16njn   // Open the suppression file.
12739264559eba4aa5d397a278b4e1a50c03de30693fsewardj   sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
1274cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   if (sr_isError(sres)) {
1275f349d55d40891b890d0da268cfb9f092af0fc8f4sewardj      if (VG_(clo_xml))
127609361bf997371238c2090cf5bacbe7f1eff90b44sewardj         VG_(printf_xml)("</valgrindoutput>\n");
1277738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
1278de4a1d01951937632098a6cda45859afa587a06fsewardj      VG_(exit)(1);
1279de4a1d01951937632098a6cda45859afa587a06fsewardj   }
1280cda2f0fbda4c4b2644babc830244be8aed95de1dnjn   fd = sr_Res(sres);
1281de4a1d01951937632098a6cda45859afa587a06fsewardj
12829264559eba4aa5d397a278b4e1a50c03de30693fsewardj#  define BOMB(S)  { err_str = S;  goto syntax_error; }
1283b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1284de4a1d01951937632098a6cda45859afa587a06fsewardj   while (True) {
12857cc9c239f785f2903b597cdb34418bed42d25331nethercote      /* Assign and initialise the two suppression halves (core and tool) */
1286810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn      Supp* supp;
128777eb20b3865e7b17c7695c7e7a526b52935f593eflorian      supp        = VG_(malloc)("errormgr.losf.1", sizeof(Supp));
1288de4a1d01951937632098a6cda45859afa587a06fsewardj      supp->count = 0;
1289b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1290b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      // Initialise temporary reading-in buffer.
1291a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes      for (i = 0; i < VG_DEEPEST_BACKTRACE; i++) {
1292b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         tmp_callers[i].ty   = NoName;
12932c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe         tmp_callers[i].name_is_simple_str = False;
1294b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         tmp_callers[i].name = NULL;
1295b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      }
1296b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1297810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn      supp->string = supp->extra = NULL;
1298de4a1d01951937632098a6cda45859afa587a06fsewardj
12992193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
13007d69fd986190ebe179ca151f7c629e17a967fbfbphilippe      if (eof) {
130177eb20b3865e7b17c7695c7e7a526b52935f593eflorian         VG_(free)(supp);
13027d69fd986190ebe179ca151f7c629e17a967fbfbphilippe         break;
13037d69fd986190ebe179ca151f7c629e17a967fbfbphilippe      }
1304de4a1d01951937632098a6cda45859afa587a06fsewardj
1305b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
1306de4a1d01951937632098a6cda45859afa587a06fsewardj
13072193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
1308b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1309b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
1310b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
131177eb20b3865e7b17c7695c7e7a526b52935f593eflorian      supp->sname = VG_(strdup)("errormgr.losf.2", buf);
1312362441db825242200142a91bb07c4a0300b36a3ephilippe      supp->clo_suppressions_i = clo_suppressions_i;
1313362441db825242200142a91bb07c4a0300b36a3ephilippe      supp->sname_lineno = lineno;
1314de4a1d01951937632098a6cda45859afa587a06fsewardj
13152193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
1316de4a1d01951937632098a6cda45859afa587a06fsewardj
13172193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      if (eof) BOMB("unexpected end-of-file (expecting tool:suppr)");
1318de4a1d01951937632098a6cda45859afa587a06fsewardj
131994065fd4f0237006763e1f8d897ec7eae55f8762njn      /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
1320c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      i = 0;
1321c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      while (True) {
1322c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn         if (buf[i] == ':')  break;
1323b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
1324c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn         i++;
1325c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      }
1326c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      buf[i]    = '\0';    /* Replace ':', splitting into two strings */
13270873c946ddd7e7d5befe22451dae3c59974dfb42sewardj
13287cc9c239f785f2903b597cdb34418bed42d25331nethercote      tool_names = & buf[0];
132911cc9257368fda337b88ef699f9383a096d6e1a9njn      supp_name  = & buf[i+1];
1330c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn
13317cc9c239f785f2903b597cdb34418bed42d25331nethercote      if (VG_(needs).core_errors && tool_name_present("core", tool_names))
1332c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      {
1333b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         // A core suppression
1334a86f29edc3d1daaf084736744a4a88c3c970e3f7njn         //(example code, see comment on CoreSuppKind above)
1335a86f29edc3d1daaf084736744a4a88c3c970e3f7njn         //if (VG_STREQ(supp_name, "Thread"))
1336a86f29edc3d1daaf084736744a4a88c3c970e3f7njn         //   supp->skind = ThreadSupp;
1337a86f29edc3d1daaf084736744a4a88c3c970e3f7njn         //else
1338b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            BOMB("unknown core suppression type");
1339e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      }
134095ec870848b73e0f90758f94f2c3e62e5c3cccefnjn      else if (VG_(needs).tool_errors &&
13417cc9c239f785f2903b597cdb34418bed42d25331nethercote               tool_name_present(VG_(details).name, tool_names))
1342c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      {
1343b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         // A tool suppression
134451d827bcd88ce045a383ea1ca81768757df2d1fanjn         if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
1345810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn            /* Do nothing, function fills in supp->skind */
1346b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         } else {
1347b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            BOMB("unknown tool suppression type");
1348b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         }
1349c40c3a837ab7b55111f213f40bc8dd9179d6d6e6njn      }
1350e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      else {
1351b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         // Ignore rest of suppression
1352e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         while (True) {
13532193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
13542193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            if (eof) BOMB("unexpected end-of-file (when skipping suppression)");
135543c799ed4de307bf00b2467b9b63e583894a030bnjn            if (VG_STREQ(buf, "}"))
1356e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn               break;
1357de4a1d01951937632098a6cda45859afa587a06fsewardj         }
135877eb20b3865e7b17c7695c7e7a526b52935f593eflorian         VG_(free)(supp->sname);
135977eb20b3865e7b17c7695c7e7a526b52935f593eflorian         VG_(free)(supp);
1360e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         continue;
1361e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      }
1362e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
13632193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      buf[0] = 0;
13642193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      // tool_read_extra_suppression_info might read lines
13652193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      // from fd till a location line.
136695ec870848b73e0f90758f94f2c3e62e5c3cccefnjn      if (VG_(needs).tool_errors &&
1367d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj          !VG_TDICT_CALL(tool_read_extra_suppression_info,
1368362441db825242200142a91bb07c4a0300b36a3ephilippe                         fd, &buf, &nBuf, &lineno, supp))
1369b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      {
1370b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         BOMB("bad or missing extra suppression info");
1371b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      }
1372e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
13732193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe      got_a_location_line_read_by_tool = buf[0] != 0 && is_location_line(buf);
13742193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe
13755e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      /* the main frame-descriptor reading loop */
1376b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      i = 0;
1377b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      while (True) {
13782193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         if (got_a_location_line_read_by_tool) {
13792193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            got_a_location_line_read_by_tool = False;
13802193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            eof = False;
13812193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         } else {
13822193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
13832193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe         }
1384b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         if (eof)
13852193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            BOMB("unexpected end-of-file (when reading stack trace)");
1386b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         if (VG_STREQ(buf, "}")) {
1387b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            if (i > 0) {
1388b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj               break;
1389b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            } else {
1390b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj               BOMB("missing stack trace");
1391b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            }
1392b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         }
1393a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes         if (i == VG_DEEPEST_BACKTRACE)
1394b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj            BOMB("too many callers in stack trace");
1395b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         if (i > 0 && i >= VG_(clo_backtrace_size))
1396633de3263f7fb249580b220e355a3760ad3ebc82njn            break;
13977d69fd986190ebe179ca151f7c629e17a967fbfbphilippe         if (!setLocationTy(&(tmp_callers[i]), buf))
13985e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj            BOMB("location should be \"...\", or should start "
13995e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj                 "with \"fun:\" or \"obj:\"");
1400b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         i++;
1401de4a1d01951937632098a6cda45859afa587a06fsewardj      }
1402de4a1d01951937632098a6cda45859afa587a06fsewardj
1403b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
1404b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      // lines and grab the '}'.
140557a8f5f43d610c639108d3afe7b32001e7ffda0dsewardj      if (!VG_STREQ(buf, "}")) {
1406b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         do {
14072193a7c20b74867de85a5ac10e7db5c7038f7c8aphilippe            eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
1408b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         } while (!eof && !VG_STREQ(buf, "}"));
1409b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      }
1410b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
14115e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      // Reject entries which are entirely composed of frame
14125e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      // level wildcards.
14135e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
14145e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      for (j = 0; j < i; j++) {
14155e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj         if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
14165e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj            break;
14175e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj         vg_assert(tmp_callers[j].ty == DotDotDot);
14185e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      }
14195e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      vg_assert(j >= 0 && j <= i);
14205e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      if (j == i) {
14215e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj         // we didn't find any non-"..." entries
14225e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj         BOMB("suppression must contain at least one location "
14235e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj              "line which is not \"...\"");
14245e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj      }
14255e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj
1426b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      // Copy tmp_callers[] into supp->callers[]
1427b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      supp->n_callers = i;
142877eb20b3865e7b17c7695c7e7a526b52935f593eflorian      supp->callers = VG_(malloc)("errormgr.losf.4", i * sizeof(SuppLoc));
1429b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj      for (i = 0; i < supp->n_callers; i++) {
1430b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj         supp->callers[i] = tmp_callers[i];
143157a8f5f43d610c639108d3afe7b32001e7ffda0dsewardj      }
143257a8f5f43d610c639108d3afe7b32001e7ffda0dsewardj
1433695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn      supp->next = suppressions;
1434695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn      suppressions = supp;
1435de4a1d01951937632098a6cda45859afa587a06fsewardj   }
143635db56c19847654f22b62da059083d41ff4258c5njn   VG_(free)(buf);
1437de4a1d01951937632098a6cda45859afa587a06fsewardj   VG_(close)(fd);
1438de4a1d01951937632098a6cda45859afa587a06fsewardj   return;
1439de4a1d01951937632098a6cda45859afa587a06fsewardj
1440de4a1d01951937632098a6cda45859afa587a06fsewardj  syntax_error:
1441f349d55d40891b890d0da268cfb9f092af0fc8f4sewardj   if (VG_(clo_xml))
144209361bf997371238c2090cf5bacbe7f1eff90b44sewardj      VG_(printf_xml)("</valgrindoutput>\n");
1443738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
14446f74a7ef1768dd3925cc22869b4e5e24e9338d08njn           filename, lineno );
1445738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(umsg)("   %s\n", err_str );
1446b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1447de4a1d01951937632098a6cda45859afa587a06fsewardj   VG_(close)(fd);
1448738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(umsg)("exiting now.\n");
14498ed8a89987e0eee428e2cf6370a1418bbe7421ednethercote   VG_(exit)(1);
1450de4a1d01951937632098a6cda45859afa587a06fsewardj
1451b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#  undef BOMB
1452de4a1d01951937632098a6cda45859afa587a06fsewardj}
1453de4a1d01951937632098a6cda45859afa587a06fsewardj
1454de4a1d01951937632098a6cda45859afa587a06fsewardj
1455de4a1d01951937632098a6cda45859afa587a06fsewardjvoid VG_(load_suppressions) ( void )
1456de4a1d01951937632098a6cda45859afa587a06fsewardj{
1457de4a1d01951937632098a6cda45859afa587a06fsewardj   Int i;
1458695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   suppressions = NULL;
14597931627282eede4440f3f329b657c3ec68371e8aflorian   for (i = 0; i < VG_(sizeXA)(VG_(clo_suppressions)); i++) {
1460de4a1d01951937632098a6cda45859afa587a06fsewardj      if (VG_(clo_verbosity) > 1) {
1461738856f99eea33d86ce91dcb1d6cd5b151e307casewardj         VG_(dmsg)("Reading suppressions file: %s\n",
14627931627282eede4440f3f329b657c3ec68371e8aflorian                   *(HChar**) VG_(indexXA)(VG_(clo_suppressions), i));
1463de4a1d01951937632098a6cda45859afa587a06fsewardj      }
1464362441db825242200142a91bb07c4a0300b36a3ephilippe      load_one_suppressions_file( i );
1465de4a1d01951937632098a6cda45859afa587a06fsewardj   }
1466de4a1d01951937632098a6cda45859afa587a06fsewardj}
1467de4a1d01951937632098a6cda45859afa587a06fsewardj
1468d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1469d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*------------------------------------------------------------*/
1470d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*--- Matching errors to suppressions                      ---*/
1471d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/*------------------------------------------------------------*/
1472d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1473d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/* Parameterising functions for the use of VG_(generic_match) in
1474d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   suppression-vs-error matching.  The suppression frames (SuppLoc)
1475d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   play the role of 'pattern'-element, and the error frames (IPs,
1476d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   hence simply Addrs) play the role of 'input'.  In short then, we're
1477d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   matching a sequence of Addrs against a pattern composed of a
1478d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   sequence of SuppLocs.
1479d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj*/
14803e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool supploc_IsStar ( const void* supplocV )
1481d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{
14823e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const SuppLoc* supploc = supplocV;
1483d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   return supploc->ty == DotDotDot;
1484d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj}
1485d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
14863e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool supploc_IsQuery ( const void* supplocV )
1487d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{
1488d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   return False; /* there's no '?' equivalent in the supp syntax */
1489d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj}
1490d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
149113a59524748a7af0f403e4aba435144fa9a6af4cphilippe/* IPtoFunOrObjCompleter is a lazy completer of the IPs
149213a59524748a7af0f403e4aba435144fa9a6af4cphilippe   needed to match an error with the suppression patterns.
149313a59524748a7af0f403e4aba435144fa9a6af4cphilippe   The matching between an IP and a suppression pattern is done either
149413a59524748a7af0f403e4aba435144fa9a6af4cphilippe   with the IP function name or with the IP object name.
149513a59524748a7af0f403e4aba435144fa9a6af4cphilippe   First time the fun or obj name is needed for an IP member
149613a59524748a7af0f403e4aba435144fa9a6af4cphilippe   of a stack trace, it will be computed and stored in names.
1497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Also, if the IP corresponds to one or more inlined function calls,
1498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   the inlined function names are expanded.
149913a59524748a7af0f403e4aba435144fa9a6af4cphilippe   The IPtoFunOrObjCompleter type is designed to minimise the nr of
150013a59524748a7af0f403e4aba435144fa9a6af4cphilippe   allocations and the nr of debuginfo search. */
150113a59524748a7af0f403e4aba435144fa9a6af4cphilippetypedef
150213a59524748a7af0f403e4aba435144fa9a6af4cphilippe   struct {
150313a59524748a7af0f403e4aba435144fa9a6af4cphilippe      StackTrace ips; // stack trace we are lazily completing.
150413a59524748a7af0f403e4aba435144fa9a6af4cphilippe      UWord n_ips; // nr of elements in ips.
150513a59524748a7af0f403e4aba435144fa9a6af4cphilippe
1506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // VG_(generic_match) calls haveInputInpC to check
1507a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // for the presence of an input element identified by ixInput
1508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // (i.e. a number that identifies the ixInput element of the
1509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // input sequence). It calls supp_pattEQinp to match this input
1510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // element with a pattern.
1511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // When inlining info is used to provide inlined function calls
1512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // in stacktraces, one IP in ips can be expanded in several
1513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // function names. So, each time input (or presence of input)
1514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // is requested by VG_(generic_match), we will expand
1515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // more IP of ips till we have expanded enough to reach the
1516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // input element requested (or we cannot expand anymore).
1517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      UWord n_ips_expanded;
1519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // n_ips_expanded maintains the nr of elements in ips that we have
1520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // already expanded.
1521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      UWord n_expanded;
1522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // n_expanded maintains the nr of elements resulting from the expansion
1523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // of the n_ips_expanded IPs. Without inlined function calls,
1524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // n_expanded == n_ips_expanded. With inlining info,
1525a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // n_expanded >= n_ips_expanded.
1526a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1527a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Int* n_offsets_per_ip;
1528c06f684badc0701961e68dbc206fbf1757f7fd68philippe      // n_offsets_per_ip[i] gives the nr of offsets in fun_offsets and
1529c06f684badc0701961e68dbc206fbf1757f7fd68philippe      // obj_offsets resulting of the expansion of ips[i].
1530a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // The sum of all n_expanded_per_ip must be equal to n_expanded.
1531c06f684badc0701961e68dbc206fbf1757f7fd68philippe      // This array allows to retrieve the position in ips corresponding to
1532c06f684badc0701961e68dbc206fbf1757f7fd68philippe      // an ixInput.
1533a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1534a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // size (in elements) of fun_offsets and obj_offsets.
1535a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // (fun|obj)_offsets are reallocated if more space is needed
1536a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // to expand an IP.
1537a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      UWord sz_offsets;
1538a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
153913a59524748a7af0f403e4aba435144fa9a6af4cphilippe      Int* fun_offsets;
1540a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // fun_offsets[ixInput] is the offset in names where the
1541a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // function name for the ixInput element of the input sequence
1542a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // can be found. As one IP of ips can be expanded in several
1543a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // function calls due to inlined function calls, we can have more
1544a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // elements in fun_offsets than in ips.
1545a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // An offset -1 means the function name has not yet been computed.
154613a59524748a7af0f403e4aba435144fa9a6af4cphilippe      Int* obj_offsets;
1547a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // Similarly, obj_offsets[ixInput] gives the offset for the
1548a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // object name for ips[ixInput]
1549a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // (-1 meaning object name not yet been computed).
155013a59524748a7af0f403e4aba435144fa9a6af4cphilippe
155113a59524748a7af0f403e4aba435144fa9a6af4cphilippe      // All function names and object names will be concatenated
155213a59524748a7af0f403e4aba435144fa9a6af4cphilippe      // in names. names is reallocated on demand.
155319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar *names;
155413a59524748a7af0f403e4aba435144fa9a6af4cphilippe      Int   names_szB;  // size of names.
155519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      Int   names_free; // offset first free HChar in names.
155613a59524748a7af0f403e4aba435144fa9a6af4cphilippe   }
155713a59524748a7af0f403e4aba435144fa9a6af4cphilippe   IPtoFunOrObjCompleter;
155813a59524748a7af0f403e4aba435144fa9a6af4cphilippe
1559518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void pp_ip2fo (const IPtoFunOrObjCompleter* ip2fo)
15605ab7ce8534933940ae16c11a98939f4dc930c62dphilippe{
15615ab7ce8534933940ae16c11a98939f4dc930c62dphilippe  Int i, j;
15625ab7ce8534933940ae16c11a98939f4dc930c62dphilippe  Int o;
15635ab7ce8534933940ae16c11a98939f4dc930c62dphilippe
15645ab7ce8534933940ae16c11a98939f4dc930c62dphilippe  VG_(printf)("n_ips %lu n_ips_expanded %lu resulting in n_expanded %lu\n",
15655ab7ce8534933940ae16c11a98939f4dc930c62dphilippe              ip2fo->n_ips, ip2fo->n_ips_expanded, ip2fo->n_expanded);
15665ab7ce8534933940ae16c11a98939f4dc930c62dphilippe  for (i = 0; i < ip2fo->n_ips_expanded; i++) {
15675ab7ce8534933940ae16c11a98939f4dc930c62dphilippe     o = 0;
15685ab7ce8534933940ae16c11a98939f4dc930c62dphilippe     for (j = 0; j < i; j++)
15695ab7ce8534933940ae16c11a98939f4dc930c62dphilippe        o += ip2fo->n_offsets_per_ip[j];
15705ab7ce8534933940ae16c11a98939f4dc930c62dphilippe     VG_(printf)("ips %d 0x08%lx offset [%d,%d] ",
15715ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                 i, ip2fo->ips[i],
15725ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                 o, o+ip2fo->n_offsets_per_ip[i]-1);
15735ab7ce8534933940ae16c11a98939f4dc930c62dphilippe     for (j = 0; j < ip2fo->n_offsets_per_ip[i]; j++) {
15745ab7ce8534933940ae16c11a98939f4dc930c62dphilippe        VG_(printf)("%sfun:%s obj:%s\n",
15755ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                    j == 0 ? "" : "                              ",
15765ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                    ip2fo->fun_offsets[o+j] == -1 ?
15775ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                    "<not expanded>" : &ip2fo->names[ip2fo->fun_offsets[o+j]],
15785ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                    ip2fo->obj_offsets[o+j] == -1 ?
15795ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                    "<not expanded>" : &ip2fo->names[ip2fo->obj_offsets[o+j]]);
15805ab7ce8534933940ae16c11a98939f4dc930c62dphilippe    }
15815ab7ce8534933940ae16c11a98939f4dc930c62dphilippe  }
15825ab7ce8534933940ae16c11a98939f4dc930c62dphilippe}
15835ab7ce8534933940ae16c11a98939f4dc930c62dphilippe
15845ab7ce8534933940ae16c11a98939f4dc930c62dphilippe/* free the memory in ip2fo.
1585c06f684badc0701961e68dbc206fbf1757f7fd68philippe   At debuglog 4, su (or NULL) will be used to show the matching
1586c06f684badc0701961e68dbc206fbf1757f7fd68philippe   (or non matching) with ip2fo. */
1587518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void clearIPtoFunOrObjCompleter ( const Supp  *su,
1588c06f684badc0701961e68dbc206fbf1757f7fd68philippe                                         IPtoFunOrObjCompleter* ip2fo)
158913a59524748a7af0f403e4aba435144fa9a6af4cphilippe{
15905ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   if (DEBUG_ERRORMGR || VG_(debugLog_getLevel)() >= 4) {
15917931627282eede4440f3f329b657c3ec68371e8aflorian      if (su) {
15927931627282eede4440f3f329b657c3ec68371e8aflorian         HChar *filename = *(HChar**) VG_(indexXA)(VG_(clo_suppressions),
15937931627282eede4440f3f329b657c3ec68371e8aflorian                                                   su->clo_suppressions_i);
15945ab7ce8534933940ae16c11a98939f4dc930c62dphilippe         VG_(dmsg)("errormgr matching end suppression %s  %s:%d matched:\n",
15955ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                   su->sname,
15967931627282eede4440f3f329b657c3ec68371e8aflorian                   filename,
15975ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                   su->sname_lineno);
15987931627282eede4440f3f329b657c3ec68371e8aflorian      } else
15995ab7ce8534933940ae16c11a98939f4dc930c62dphilippe         VG_(dmsg)("errormgr matching end no suppression matched:\n");
16005ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      VG_(pp_StackTrace) (ip2fo->ips, ip2fo->n_ips);
16015ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      pp_ip2fo(ip2fo);
16025ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   }
1603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->n_offsets_per_ip) VG_(free)(ip2fo->n_offsets_per_ip);
1604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->fun_offsets)      VG_(free)(ip2fo->fun_offsets);
1605a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->obj_offsets)      VG_(free)(ip2fo->obj_offsets);
1606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->names)            VG_(free)(ip2fo->names);
160713a59524748a7af0f403e4aba435144fa9a6af4cphilippe}
160813a59524748a7af0f403e4aba435144fa9a6af4cphilippe
160946cc04521acf2827eb33310fadc119bf2dc039e4florian/* Grow ip2fo->names to ensure we have NEEDED characters available
1610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   in ip2fo->names and returns a pointer to the first free char. */
161146cc04521acf2827eb33310fadc119bf2dc039e4florianstatic HChar* grow_names(IPtoFunOrObjCompleter* ip2fo, SizeT needed)
1612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->names_szB
161446cc04521acf2827eb33310fadc119bf2dc039e4florian       < ip2fo->names_free + needed) {
161546cc04521acf2827eb33310fadc119bf2dc039e4florian     if (needed < ERRTXT_LEN) needed = ERRTXT_LEN;
161646cc04521acf2827eb33310fadc119bf2dc039e4florian
1617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ip2fo->names
1618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = VG_(realloc)("foc_names",
1619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        ip2fo->names,
162046cc04521acf2827eb33310fadc119bf2dc039e4florian                        ip2fo->names_szB + needed);
162146cc04521acf2827eb33310fadc119bf2dc039e4florian      ip2fo->names_szB += needed;
1622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   return ip2fo->names + ip2fo->names_free;
1624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* foComplete returns the function name or object name for ixInput.
1627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   If needFun, returns the function name for this input
1628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   else returns the object name for this input.
162913a59524748a7af0f403e4aba435144fa9a6af4cphilippe   The function name or object name will be computed and added in
1630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   names if not yet done. */
163119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianstatic HChar* foComplete(IPtoFunOrObjCompleter* ip2fo,
1632a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         Int ixInput, Bool needFun)
163313a59524748a7af0f403e4aba435144fa9a6af4cphilippe{
1634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   vg_assert (ixInput < ip2fo->n_expanded);
1635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   vg_assert (VG_(clo_read_inline_info) || ixInput < ip2fo->n_ips);
163613a59524748a7af0f403e4aba435144fa9a6af4cphilippe
163713a59524748a7af0f403e4aba435144fa9a6af4cphilippe   // ptr to the offset array for function offsets (if needFun)
163813a59524748a7af0f403e4aba435144fa9a6af4cphilippe   // or object offsets (if !needFun).
163913a59524748a7af0f403e4aba435144fa9a6af4cphilippe   Int** offsets;
164013a59524748a7af0f403e4aba435144fa9a6af4cphilippe   if (needFun)
164113a59524748a7af0f403e4aba435144fa9a6af4cphilippe      offsets = &ip2fo->fun_offsets;
164213a59524748a7af0f403e4aba435144fa9a6af4cphilippe   else
164313a59524748a7af0f403e4aba435144fa9a6af4cphilippe      offsets = &ip2fo->obj_offsets;
164413a59524748a7af0f403e4aba435144fa9a6af4cphilippe
164513a59524748a7af0f403e4aba435144fa9a6af4cphilippe   // Complete Fun name or Obj name for IP if not yet done.
1646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if ((*offsets)[ixInput] == -1) {
164746cc04521acf2827eb33310fadc119bf2dc039e4florian      const HChar* caller;
164846cc04521acf2827eb33310fadc119bf2dc039e4florian
1649a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      (*offsets)[ixInput] = ip2fo->names_free;
16505ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      if (DEBUG_ERRORMGR) VG_(printf)("marking %s ixInput %d offset %d\n",
16515ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                                      needFun ? "fun" : "obj",
16525ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                                      ixInput, ip2fo->names_free);
165313a59524748a7af0f403e4aba435144fa9a6af4cphilippe      if (needFun) {
1654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // With inline info, fn names must have been completed already.
1655a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert (!VG_(clo_read_inline_info));
165613a59524748a7af0f403e4aba435144fa9a6af4cphilippe         /* Get the function name into 'caller_name', or "???"
165713a59524748a7af0f403e4aba435144fa9a6af4cphilippe            if unknown. */
165813a59524748a7af0f403e4aba435144fa9a6af4cphilippe         // Nb: C++-mangled names are used in suppressions.  Do, though,
165913a59524748a7af0f403e4aba435144fa9a6af4cphilippe         // Z-demangle them, since otherwise it's possible to wind
166013a59524748a7af0f403e4aba435144fa9a6af4cphilippe         // up comparing "malloc" in the suppression against
166113a59524748a7af0f403e4aba435144fa9a6af4cphilippe         // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
166213a59524748a7af0f403e4aba435144fa9a6af4cphilippe         // two of them need to be made to match.
1663a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (!VG_(get_fnname_no_cxx_demangle)(ip2fo->ips[ixInput],
166446cc04521acf2827eb33310fadc119bf2dc039e4florian                                              &caller,
1665a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                              NULL))
166646cc04521acf2827eb33310fadc119bf2dc039e4florian            caller = "???";
166713a59524748a7af0f403e4aba435144fa9a6af4cphilippe      } else {
166813a59524748a7af0f403e4aba435144fa9a6af4cphilippe         /* Get the object name into 'caller_name', or "???"
166913a59524748a7af0f403e4aba435144fa9a6af4cphilippe            if unknown. */
1670a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         UWord i;
1671a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         UWord last_expand_pos_ips = 0;
1672a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         UWord pos_ips;
1673a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1674a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* First get the pos in ips corresponding to ixInput */
1675a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         for (pos_ips = 0; pos_ips < ip2fo->n_expanded; pos_ips++) {
1676a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            last_expand_pos_ips += ip2fo->n_offsets_per_ip[pos_ips];
16775ab7ce8534933940ae16c11a98939f4dc930c62dphilippe            if (ixInput < last_expand_pos_ips)
1678a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               break;
1679a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
1680a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* pos_ips is the position in ips corresponding to ixInput.
1681a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            last_expand_pos_ips is the last offset in fun/obj where
1682a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ips[pos_ips] has been expanded. */
1683a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
168446cc04521acf2827eb33310fadc119bf2dc039e4florian         if (!VG_(get_objname)(ip2fo->ips[pos_ips], &caller))
168546cc04521acf2827eb33310fadc119bf2dc039e4florian            caller = "???";
1686a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1687a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // Have all inlined calls pointing at this object name
16885ab7ce8534933940ae16c11a98939f4dc930c62dphilippe         for (i = last_expand_pos_ips - ip2fo->n_offsets_per_ip[pos_ips] + 1;
16895ab7ce8534933940ae16c11a98939f4dc930c62dphilippe              i < last_expand_pos_ips;
16905ab7ce8534933940ae16c11a98939f4dc930c62dphilippe              i++) {
1691a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip2fo->obj_offsets[i] = ip2fo->names_free;
16925ab7ce8534933940ae16c11a98939f4dc930c62dphilippe            if (DEBUG_ERRORMGR)
1693c06f684badc0701961e68dbc206fbf1757f7fd68philippe               VG_(printf) ("   set obj_offset %lu to %d\n",
1694c06f684badc0701961e68dbc206fbf1757f7fd68philippe                            i, ip2fo->names_free);
16955ab7ce8534933940ae16c11a98939f4dc930c62dphilippe         }
169613a59524748a7af0f403e4aba435144fa9a6af4cphilippe      }
169746cc04521acf2827eb33310fadc119bf2dc039e4florian      SizeT  caller_len = VG_(strlen)(caller);
169846cc04521acf2827eb33310fadc119bf2dc039e4florian      HChar* caller_name = grow_names(ip2fo, caller_len + 1);
169946cc04521acf2827eb33310fadc119bf2dc039e4florian      VG_(strcpy)(caller_name, caller);
170046cc04521acf2827eb33310fadc119bf2dc039e4florian      ip2fo->names_free += caller_len + 1;
17015ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      if (DEBUG_ERRORMGR) pp_ip2fo(ip2fo);
170213a59524748a7af0f403e4aba435144fa9a6af4cphilippe   }
170313a59524748a7af0f403e4aba435144fa9a6af4cphilippe
1704a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   return ip2fo->names + (*offsets)[ixInput];
1705a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1706a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1707a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe// Grow fun and obj _offsets arrays to have at least n_req elements.
1708a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe// Ensure n_offsets_per_ip is allocated.
1709a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void grow_offsets(IPtoFunOrObjCompleter* ip2fo, Int n_req)
1710a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1711a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Int i;
1712a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1713a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // n_offsets_per_ip must always have the size of the ips array
1714a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->n_offsets_per_ip == NULL) {
1715a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ip2fo->n_offsets_per_ip = VG_(malloc)("grow_offsets",
1716a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                            ip2fo->n_ips * sizeof(Int));
1717a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < ip2fo->n_ips; i++)
1718a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip2fo->n_offsets_per_ip[i] = 0;
1719a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1720a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1721a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ip2fo->sz_offsets >= n_req)
1722a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      return;
1723a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1724a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // Avoid too much re-allocation by allocating at least ip2fo->n_ips
1725a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // elements and at least a few more elements than the current size.
1726a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (n_req < ip2fo->n_ips)
1727a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n_req = ip2fo->n_ips;
1728a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (n_req < ip2fo->sz_offsets + 5)
1729a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n_req = ip2fo->sz_offsets + 5;
1730a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1731a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo->fun_offsets = VG_(realloc)("grow_offsets", ip2fo->fun_offsets,
1732a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                     n_req * sizeof(Int));
1733a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   for (i = ip2fo->sz_offsets; i < n_req; i++)
1734a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ip2fo->fun_offsets[i] = -1;
1735a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1736a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo->obj_offsets = VG_(realloc)("grow_offsets", ip2fo->obj_offsets,
1737a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                     n_req * sizeof(Int));
1738a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   for (i = ip2fo->sz_offsets; i < n_req; i++)
1739a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ip2fo->obj_offsets[i] = -1;
1740a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1741a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo->sz_offsets = n_req;
1742a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1743a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1744a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe// Expands more IPs from ip2fo->ips.
1745a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void expandInput (IPtoFunOrObjCompleter* ip2fo, UWord ixInput )
1746a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1747a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   while (ip2fo->n_ips_expanded < ip2fo->n_ips
1748a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe          && ip2fo->n_expanded <= ixInput) {
1749a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (VG_(clo_read_inline_info)) {
1750a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // Expand one more IP in one or more calls.
1751a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         const Addr IP = ip2fo->ips[ip2fo->n_ips_expanded];
1752a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         InlIPCursor *iipc;
1753a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1754a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         iipc = VG_(new_IIPC)(IP);
1755a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // The only thing we really need is the nr of inlined fn calls
1756a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // corresponding to the IP we will expand.
1757a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // However, computing this is mostly the same as finding
1758a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // the function name. So, let's directly complete the function name.
1759a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         do {
176046cc04521acf2827eb33310fadc119bf2dc039e4florian            const HChar *caller;
1761a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            grow_offsets(ip2fo, ip2fo->n_expanded+1);
1762a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip2fo->fun_offsets[ip2fo->n_expanded] = ip2fo->names_free;
1763a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (!VG_(get_fnname_no_cxx_demangle)(IP,
176446cc04521acf2827eb33310fadc119bf2dc039e4florian                                                 &caller,
1765a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                                 iipc))
176646cc04521acf2827eb33310fadc119bf2dc039e4florian               caller = "???";
176746cc04521acf2827eb33310fadc119bf2dc039e4florian            SizeT  caller_len = VG_(strlen)(caller);
176846cc04521acf2827eb33310fadc119bf2dc039e4florian            HChar* caller_name = grow_names(ip2fo, caller_len + 1);
176946cc04521acf2827eb33310fadc119bf2dc039e4florian            VG_(strcpy)(caller_name, caller);
177046cc04521acf2827eb33310fadc119bf2dc039e4florian            ip2fo->names_free += caller_len + 1;
1771a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip2fo->n_expanded++;
1772a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip2fo->n_offsets_per_ip[ip2fo->n_ips_expanded]++;
1773a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         } while (VG_(next_IIPC)(iipc));
1774a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip2fo->n_ips_expanded++;
1775a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(delete_IIPC) (iipc);
1776a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else {
1777a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // Without inlined fn call info, expansion simply
1778a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // consists in allocating enough elements in (fun|obj)_offsets.
1779a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // The function or object names themselves will be completed
1780a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // when requested.
1781a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         Int i;
1782a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         grow_offsets(ip2fo, ip2fo->n_ips);
1783a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip2fo->n_ips_expanded = ip2fo->n_ips;
1784a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip2fo->n_expanded = ip2fo->n_ips;
1785a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         for (i = 0; i < ip2fo->n_ips; i++)
1786a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip2fo->n_offsets_per_ip[i] = 1;
1787a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
1788a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1789a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1790a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1791a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool haveInputInpC (void* inputCompleter, UWord ixInput )
1792a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1793a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   IPtoFunOrObjCompleter* ip2fo = inputCompleter;
1794a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   expandInput(ip2fo, ixInput);
1795a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   return ixInput < ip2fo->n_expanded;
179613a59524748a7af0f403e4aba435144fa9a6af4cphilippe}
179713a59524748a7af0f403e4aba435144fa9a6af4cphilippe
17983e7986312a0ffc7646b0552d4c4ea3744a870e73florianstatic Bool supp_pattEQinp ( const void* supplocV, const void* addrV,
1799a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             void* inputCompleter, UWord ixInput )
1800d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{
18013e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const SuppLoc* supploc = supplocV; /* PATTERN */
18023e7986312a0ffc7646b0552d4c4ea3744a870e73florian   IPtoFunOrObjCompleter* ip2fo = inputCompleter;
180319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* funobj_name; // Fun or Obj name.
18045ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   Bool ret;
1805d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1806a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   expandInput(ip2fo, ixInput);
1807a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   vg_assert(ixInput < ip2fo->n_expanded);
1808a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1809d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   /* So, does this IP address match this suppression-line? */
1810d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   switch (supploc->ty) {
1811d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      case DotDotDot:
1812d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj         /* supp_pattEQinp is a callback from VG_(generic_match).  As
1813d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj            per the spec thereof (see include/pub_tool_seqmatch.h), we
1814d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj            should never get called with a pattern value for which the
1815d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj            _IsStar or _IsQuery function would return True.  Hence
1816d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj            this can't happen. */
1817d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj         vg_assert(0);
1818d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      case ObjName:
1819a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         funobj_name = foComplete(ip2fo, ixInput, False /*needFun*/);
1820d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj         break;
182113a59524748a7af0f403e4aba435144fa9a6af4cphilippe      case FunName:
1822a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         funobj_name = foComplete(ip2fo, ixInput, True /*needFun*/);
1823d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj         break;
1824d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      default:
1825d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj        vg_assert(0);
1826d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   }
1827d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
182813a59524748a7af0f403e4aba435144fa9a6af4cphilippe   /* So now we have the function or object name in funobj_name, and
1829d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      the pattern (at the character level) to match against is in
1830d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      supploc->name.  Hence (and leading to a re-entrant call of
18312c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe      VG_(generic_match) if there is a wildcard character): */
18322c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe   if (supploc->name_is_simple_str)
18335ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      ret = VG_(strcmp) (supploc->name, funobj_name) == 0;
18342c5c05e66ad14b3ce39c39d97a17c7588c98aa6bphilippe   else
18355ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      ret = VG_(string_match)(supploc->name, funobj_name);
18365ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   if (DEBUG_ERRORMGR)
18375ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      VG_(printf) ("supp_pattEQinp %s patt %s ixUnput %lu value:%s match:%s\n",
18385ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                   supploc->ty == FunName ? "fun" : "obj",
18395ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                   supploc->name, ixInput, funobj_name,
18405ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                   ret ? "yes" : "no");
18415ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   return ret;
1842d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj}
1843d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1844d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/////////////////////////////////////////////////////
1845d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1846518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Bool supp_matches_callers(IPtoFunOrObjCompleter* ip2fo,
1847518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                 const Supp* su)
1848d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj{
1849d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   /* Unwrap the args and set up the correct parameterisation of
1850d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
1851d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      supp_pattEQinp. */
185213a59524748a7af0f403e4aba435144fa9a6af4cphilippe   /* note, StackTrace ip2fo->ips === Addr* */
1853d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   SuppLoc*   supps    = su->callers;
1854d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   UWord      n_supps  = su->n_callers;
1855d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   UWord      szbPatt  = sizeof(SuppLoc);
1856d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   Bool       matchAll = False; /* we just want to match a prefix */
18577931627282eede4440f3f329b657c3ec68371e8aflorian   if (DEBUG_ERRORMGR) {
18587931627282eede4440f3f329b657c3ec68371e8aflorian      HChar *filename = *(HChar**) VG_(indexXA)(VG_(clo_suppressions),
18597931627282eede4440f3f329b657c3ec68371e8aflorian                                                su->clo_suppressions_i);
18605ab7ce8534933940ae16c11a98939f4dc930c62dphilippe      VG_(dmsg)("   errormgr Checking match with  %s  %s:%d\n",
18615ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                su->sname,
18627931627282eede4440f3f329b657c3ec68371e8aflorian                filename,
18635ab7ce8534933940ae16c11a98939f4dc930c62dphilippe                su->sname_lineno);
18647931627282eede4440f3f329b657c3ec68371e8aflorian   }
1865d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj   return
1866d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      VG_(generic_match)(
1867d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj         matchAll,
1868a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /*PATT*/supps, szbPatt, n_supps, 0/*initial ixPatt*/,
1869a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /*INPUT*/
1870a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         NULL, 0, 0, /* input/szbInput/nInput 0, as using an inputCompleter */
1871a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         0/*initial ixInput*/,
187213a59524748a7af0f403e4aba435144fa9a6af4cphilippe         supploc_IsStar, supploc_IsQuery, supp_pattEQinp,
1873a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip2fo, haveInputInpC
1874d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj      );
1875d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj}
1876d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1877d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/////////////////////////////////////////////////////
1878d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj
1879b5f6f51ebcac183818061bf53427a3e7808ef10dsewardjstatic
1880518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool supp_matches_error(const Supp* su, const Error* err)
1881e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn{
1882810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   switch (su->skind) {
1883a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //(example code, see comment on CoreSuppKind above)
1884a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //case ThreadSupp:
1885a86f29edc3d1daaf084736744a4a88c3c970e3f7njn      //   return (err->ekind == ThreadErr);
1886e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn      default:
188795ec870848b73e0f90758f94f2c3e62e5c3cccefnjn         if (VG_(needs).tool_errors) {
188851d827bcd88ce045a383ea1ca81768757df2d1fanjn            return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
1889e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         } else {
1890e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn            VG_(printf)(
189195ec870848b73e0f90758f94f2c3e62e5c3cccefnjn               "\nUnhandled suppression type: %u.  VG_(needs).tool_errors\n"
1892e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn               "probably needs to be set.\n",
1893a5e06c36bf9d93461bc8c4351e960888020ea1c4florian               (UInt)err->ekind);
1894a4ca4fef8c189e861492e1e2b36b52ba3fca1725florian            VG_(core_panic)("unhandled suppression type");
1895e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         }
1896e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   }
1897e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn}
1898e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
1899d7a02db0e48d2f7681a555a4594ff10f2ef54530sewardj/////////////////////////////////////////////////////
19005e519304088c312f7f46cbdf2c18f68dbe9d2954sewardj
1901810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn/* Does an error context match a suppression?  ie is this a suppressible
1902810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   error?  If so, return a pointer to the Supp record, otherwise NULL.
1903e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Tries to minimise the number of symbol searches since they are expensive.
1904de4a1d01951937632098a6cda45859afa587a06fsewardj*/
1905518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Supp* is_suppressible_error ( const Error* err )
1906de4a1d01951937632098a6cda45859afa587a06fsewardj{
1907810086f9489e1cb373bcfc15ab94a3fa3ec403f3njn   Supp* su;
19088a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   Supp* su_prev;
19098a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
191013a59524748a7af0f403e4aba435144fa9a6af4cphilippe   IPtoFunOrObjCompleter ip2fo;
191113a59524748a7af0f403e4aba435144fa9a6af4cphilippe   /* Conceptually, ip2fo contains an array of function names and an array of
191213a59524748a7af0f403e4aba435144fa9a6af4cphilippe      object names, corresponding to the array of IP of err->where.
191313a59524748a7af0f403e4aba435144fa9a6af4cphilippe      These names are just computed 'on demand' (so once maximum),
19144e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      then stored (efficiently, avoiding too many allocs) in ip2fo to be
19154e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      re-usable for the matching of the same IP with the next suppression
19164e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe      pattern.
191713a59524748a7af0f403e4aba435144fa9a6af4cphilippe
191813a59524748a7af0f403e4aba435144fa9a6af4cphilippe      VG_(generic_match) gets this 'IP to Fun or Obj name completer' as one
191913a59524748a7af0f403e4aba435144fa9a6af4cphilippe      of its arguments. It will then pass it to the function
192013a59524748a7af0f403e4aba435144fa9a6af4cphilippe      supp_pattEQinp which will then lazily complete the IP function name or
192113a59524748a7af0f403e4aba435144fa9a6af4cphilippe      object name inside ip2fo. Next time the fun or obj name for the same
192213a59524748a7af0f403e4aba435144fa9a6af4cphilippe      IP is needed (i.e. for the matching with the next suppr pattern), then
192313a59524748a7af0f403e4aba435144fa9a6af4cphilippe      the fun or obj name will not be searched again in the debug info. */
192413a59524748a7af0f403e4aba435144fa9a6af4cphilippe
19258a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   /* stats gathering */
19268a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   em_supplist_searches++;
1927de4a1d01951937632098a6cda45859afa587a06fsewardj
192813a59524748a7af0f403e4aba435144fa9a6af4cphilippe   /* Prepare the lazy input completer. */
192913a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.ips = VG_(get_ExeContext_StackTrace)(err->where);
193013a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.n_ips = VG_(get_ExeContext_n_ips)(err->where);
1931a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo.n_ips_expanded = 0;
1932a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo.n_expanded = 0;
1933a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo.sz_offsets = 0;
1934a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ip2fo.n_offsets_per_ip = NULL;
193513a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.fun_offsets = NULL;
193613a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.obj_offsets = NULL;
193713a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.names = NULL;
193813a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.names_szB = 0;
193913a59524748a7af0f403e4aba435144fa9a6af4cphilippe   ip2fo.names_free = 0;
194013a59524748a7af0f403e4aba435144fa9a6af4cphilippe
1941de4a1d01951937632098a6cda45859afa587a06fsewardj   /* See if the error context matches any suppression. */
19425ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   if (DEBUG_ERRORMGR || VG_(debugLog_getLevel)() >= 4)
19435ab7ce8534933940ae16c11a98939f4dc930c62dphilippe     VG_(dmsg)("errormgr matching begin\n");
19448a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   su_prev = NULL;
1945695c16e4b8b6d09a2c8127f6a0015b45d6194b88njn   for (su = suppressions; su != NULL; su = su->next) {
19468a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      em_supplist_cmps++;
194713a59524748a7af0f403e4aba435144fa9a6af4cphilippe      if (supp_matches_error(su, err)
194813a59524748a7af0f403e4aba435144fa9a6af4cphilippe          && supp_matches_callers(&ip2fo, su)) {
19494e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         /* got a match.  */
19504e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         /* Inform the tool that err is suppressed by su. */
19514e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         (void)VG_TDICT_CALL(tool_update_extra_suppression_use, err, su);
19524e32d67a5b880bf1d871c5141822078d4dcdc3acphilippe         /* Move this entry to the head of the list
19538a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj            in the hope of making future searches cheaper. */
19548a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         if (su_prev) {
19558a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj            vg_assert(su_prev->next == su);
19568a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj            su_prev->next = su->next;
19578a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj            su->next = suppressions;
19588a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj            suppressions = su;
19598a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj         }
19605ab7ce8534933940ae16c11a98939f4dc930c62dphilippe         clearIPtoFunOrObjCompleter(su, &ip2fo);
1961e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn         return su;
1962de4a1d01951937632098a6cda45859afa587a06fsewardj      }
19638a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      su_prev = su;
1964de4a1d01951937632098a6cda45859afa587a06fsewardj   }
19655ab7ce8534933940ae16c11a98939f4dc930c62dphilippe   clearIPtoFunOrObjCompleter(NULL, &ip2fo);
1966e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   return NULL;      /* no matches */
1967de4a1d01951937632098a6cda45859afa587a06fsewardj}
1968de4a1d01951937632098a6cda45859afa587a06fsewardj
19698a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj/* Show accumulated error-list and suppression-list search stats.
19708a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj*/
19718a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardjvoid VG_(print_errormgr_stats) ( void )
19728a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj{
1973738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(dmsg)(
1974738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
19758a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      em_supplist_searches, em_supplist_cmps
19768a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   );
1977738856f99eea33d86ce91dcb1d6cd5b151e307casewardj   VG_(dmsg)(
1978738856f99eea33d86ce91dcb1d6cd5b151e307casewardj      " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
19798a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj      em_errlist_searches, em_errlist_cmps
19808a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj   );
19818a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj}
19828a7d4e41e902b91e3b0c9a48a7f124e007270bdfsewardj
1983de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/
1984eb8896b58301a0a7a34281384d705072994369f0njn/*--- end                                                          ---*/
1985de4a1d01951937632098a6cda45859afa587a06fsewardj/*--------------------------------------------------------------------*/
1986