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