blob: e7de4eb2e9e81490324e4fbaff1072d16740c9f0 [file] [log] [blame]
sewardjde4a1d02002-03-22 01:27:54 +00001
2/*--------------------------------------------------------------------*/
sewardj267100d2005-04-24 12:33:12 +00003/*--- Management of error messages. m_errormgr.c ---*/
sewardjde4a1d02002-03-22 01:27:54 +00004/*--------------------------------------------------------------------*/
5
6/*
njnb9c427c2004-12-01 14:14:42 +00007 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
sewardjde4a1d02002-03-22 01:27:54 +00009
sewardj0f157dd2013-10-18 14:27:36 +000010 Copyright (C) 2000-2013 Julian Seward
sewardjde4a1d02002-03-22 01:27:54 +000011 jseward@acm.org
sewardjde4a1d02002-03-22 01:27:54 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
njn25e49d8e72002-09-23 09:36:25 +000028 The GNU General Public License is contained in the file COPYING.
sewardjde4a1d02002-03-22 01:27:54 +000029*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
sewardj4cfea4f2006-10-14 19:26:10 +000032#include "pub_core_vki.h"
sewardj6c591e12011-04-11 16:17:51 +000033#include "pub_core_libcsetjmp.h"
njn24a6efb2005-06-20 03:36:51 +000034#include "pub_core_threadstate.h" // For VG_N_THREADS
njn75b65aa2005-06-19 19:25:44 +000035#include "pub_core_debugger.h"
njnea27e462005-05-31 02:38:09 +000036#include "pub_core_debuginfo.h"
philippe5ab7ce82014-06-24 20:48:25 +000037#include "pub_core_debuglog.h"
njnd2b17112005-04-19 04:10:25 +000038#include "pub_core_errormgr.h"
njnd01fef72005-03-25 23:35:48 +000039#include "pub_core_execontext.h"
sewardj3b290482011-05-06 21:02:55 +000040#include "pub_core_gdbserver.h"
njn97405b22005-06-02 03:39:33 +000041#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000042#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000043#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000044#include "pub_core_libcprint.h"
njn24a6efb2005-06-20 03:36:51 +000045#include "pub_core_libcproc.h" // For VG_(getpid)()
sewardjd7a02db2008-12-12 08:07:49 +000046#include "pub_core_seqmatch.h"
njnaf1d7df2005-06-11 01:31:52 +000047#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000048#include "pub_core_options.h"
njnd0d7c1f2005-06-21 00:33:19 +000049#include "pub_core_stacktrace.h"
njn43b9a8a2005-05-10 04:37:01 +000050#include "pub_core_tooliface.h"
njn24a6efb2005-06-20 03:36:51 +000051#include "pub_core_translate.h" // for VG_(translate)()
sewardj588adef2009-08-15 22:41:51 +000052#include "pub_core_xarray.h" // VG_(xaprintf) et al
sewardjde4a1d02002-03-22 01:27:54 +000053
philippe5ab7ce82014-06-24 20:48:25 +000054#define DEBUG_ERRORMGR 0 // set to 1 for heavyweight tracing
55
sewardjde4a1d02002-03-22 01:27:54 +000056/*------------------------------------------------------------*/
njn25e49d8e72002-09-23 09:36:25 +000057/*--- Globals ---*/
sewardjde4a1d02002-03-22 01:27:54 +000058/*------------------------------------------------------------*/
59
njn14319cc2005-03-13 06:26:22 +000060/* After this many different unsuppressed errors have been observed,
61 be more conservative about collecting new ones. */
sewardj1d1a2262005-10-20 01:57:29 +000062#define M_COLLECT_ERRORS_SLOWLY_AFTER 100
njn14319cc2005-03-13 06:26:22 +000063
64/* After this many different unsuppressed errors have been observed,
65 stop collecting errors at all, and tell the user their program is
66 evidently a steaming pile of camel dung. */
sewardj1d1a2262005-10-20 01:57:29 +000067#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000
njn14319cc2005-03-13 06:26:22 +000068
69/* After this many total errors have been observed, stop collecting
70 errors at all. Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
sewardj513646f2006-05-12 23:12:30 +000071#define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000
njn14319cc2005-03-13 06:26:22 +000072
sewardjde4a1d02002-03-22 01:27:54 +000073/* The list of error contexts found, both suppressed and unsuppressed.
74 Initially empty, and grows as errors are detected. */
njn695c16e2005-03-27 03:40:28 +000075static Error* errors = NULL;
sewardjde4a1d02002-03-22 01:27:54 +000076
77/* The list of suppression directives, as read from the specified
sewardj8a7d4e42006-10-17 01:41:17 +000078 suppressions file. Note that the list gets rearranged as a result
79 of the searches done by is_suppressible_error(). */
njn695c16e2005-03-27 03:40:28 +000080static Supp* suppressions = NULL;
sewardjde4a1d02002-03-22 01:27:54 +000081
82/* Running count of unsuppressed errors detected. */
nethercotef2b11482004-08-02 12:36:01 +000083static UInt n_errs_found = 0;
sewardjde4a1d02002-03-22 01:27:54 +000084
85/* Running count of suppressed errors detected. */
nethercotef2b11482004-08-02 12:36:01 +000086static UInt n_errs_suppressed = 0;
sewardjde4a1d02002-03-22 01:27:54 +000087
philippebaf69642012-02-15 22:29:30 +000088/* Running count of errors shown. */
89static UInt n_errs_shown = 0;
90
njn606a4ae2009-08-11 00:52:40 +000091/* Running count of unsuppressed error contexts. */
92static UInt n_err_contexts = 0;
93
94/* Running count of suppressed error contexts. */
95static UInt n_supp_contexts = 0;
96
97
sewardjde4a1d02002-03-22 01:27:54 +000098/* forwards ... */
njn810086f2002-11-14 12:42:47 +000099static Supp* is_suppressible_error ( Error* err );
sewardjde4a1d02002-03-22 01:27:54 +0000100
sewardjb5f6f512005-03-10 23:59:00 +0000101static ThreadId last_tid_printed = 1;
sewardjde4a1d02002-03-22 01:27:54 +0000102
sewardj8a7d4e42006-10-17 01:41:17 +0000103/* Stats: number of searches of the error list initiated. */
104static UWord em_errlist_searches = 0;
105
106/* Stats: number of comparisons done during error list
107 searching. */
108static UWord em_errlist_cmps = 0;
109
110/* Stats: number of searches of the suppression list initiated. */
111static UWord em_supplist_searches = 0;
112
113/* Stats: number of comparisons done during suppression list
114 searching. */
115static UWord em_supplist_cmps = 0;
116
sewardjde4a1d02002-03-22 01:27:54 +0000117/*------------------------------------------------------------*/
nethercote4a184902004-08-02 12:21:09 +0000118/*--- Error type ---*/
119/*------------------------------------------------------------*/
120
nethercote4a184902004-08-02 12:21:09 +0000121/* Errors. Extensible (via the 'extra' field). Tools can use a normal
njn02bc4b82005-05-15 17:28:26 +0000122 enum (with element values in the normal range (0..)) for 'ekind'.
nethercote4a184902004-08-02 12:21:09 +0000123 Functions for getting/setting the tool-relevant fields are in
njnc7561b92005-06-19 01:24:32 +0000124 include/pub_tool_errormgr.h.
nethercote4a184902004-08-02 12:21:09 +0000125
126 When errors are found and recorded with VG_(maybe_record_error)(), all
127 the tool must do is pass in the four parameters; core will
128 allocate/initialise the error record.
129*/
130struct _Error {
131 struct _Error* next;
sewardjdbada272005-07-02 21:16:30 +0000132 // Unique tag. This gives the error a unique identity (handle) by
133 // which it can be referred to afterwords. Currently only used for
134 // XML printing.
135 UInt unique;
nethercote4a184902004-08-02 12:21:09 +0000136 // NULL if unsuppressed; or ptr to suppression record.
137 Supp* supp;
138 Int count;
nethercote4a184902004-08-02 12:21:09 +0000139
140 // The tool-specific part
sewardjb8b79ad2008-03-03 01:35:41 +0000141 ThreadId tid; // Initialised by core
nethercote4a184902004-08-02 12:21:09 +0000142 ExeContext* where; // Initialised by core
njnd2b17112005-04-19 04:10:25 +0000143 ErrorKind ekind; // Used by ALL. Must be in the range (0..)
nethercote4a184902004-08-02 12:21:09 +0000144 Addr addr; // Used frequently
floriane543f302012-10-21 19:43:43 +0000145 const HChar* string; // Used frequently
nethercote4a184902004-08-02 12:21:09 +0000146 void* extra; // For any tool-specific extras
147};
148
sewardjb8b79ad2008-03-03 01:35:41 +0000149
nethercote4a184902004-08-02 12:21:09 +0000150ExeContext* VG_(get_error_where) ( Error* err )
151{
152 return err->where;
153}
154
155ErrorKind VG_(get_error_kind) ( Error* err )
156{
157 return err->ekind;
158}
159
160Addr VG_(get_error_address) ( Error* err )
161{
162 return err->addr;
163}
164
floriane543f302012-10-21 19:43:43 +0000165const HChar* VG_(get_error_string) ( Error* err )
nethercote4a184902004-08-02 12:21:09 +0000166{
167 return err->string;
168}
169
170void* VG_(get_error_extra) ( Error* err )
171{
172 return err->extra;
173}
174
nethercotef2b11482004-08-02 12:36:01 +0000175UInt VG_(get_n_errs_found)( void )
176{
177 return n_errs_found;
178}
179
philippebaf69642012-02-15 22:29:30 +0000180UInt VG_(get_n_errs_shown)( void )
181{
182 return n_errs_shown;
183}
184
nethercote4a184902004-08-02 12:21:09 +0000185/*------------------------------------------------------------*/
186/*--- Suppression type ---*/
187/*------------------------------------------------------------*/
188
189/* Note: it is imperative this doesn't overlap with (0..) at all, as tools
190 * effectively extend it by defining their own enums in the (0..) range. */
191typedef
192 enum {
njna86f29e2006-12-14 02:55:58 +0000193 // Nb: thread errors are a relic of the time when Valgrind's core
194 // could detect them. This example is left commented-out as an
195 // example should new core errors ever be added.
196 ThreadSupp = -1, /* Matches ThreadErr */
nethercote4a184902004-08-02 12:21:09 +0000197 }
198 CoreSuppKind;
199
sewardjb5f6f512005-03-10 23:59:00 +0000200/* Max number of callers for context in a suppression. */
201#define VG_MAX_SUPP_CALLERS 24
202
nethercote4a184902004-08-02 12:21:09 +0000203/* For each caller specified for a suppression, record the nature of
204 the caller name. Not of interest to tools. */
205typedef
206 enum {
sewardjb5f6f512005-03-10 23:59:00 +0000207 NoName, /* Error case */
nethercote4a184902004-08-02 12:21:09 +0000208 ObjName, /* Name is of an shared object file. */
sewardj5e519302008-11-03 23:10:25 +0000209 FunName, /* Name is of a function. */
210 DotDotDot /* Frame-level wildcard */
nethercote4a184902004-08-02 12:21:09 +0000211 }
212 SuppLocTy;
213
sewardjb5f6f512005-03-10 23:59:00 +0000214typedef
215 struct {
216 SuppLocTy ty;
philippe2c5c05e2012-07-26 21:37:36 +0000217 Bool name_is_simple_str; /* True if name is a string without
218 '?' and '*' wildcard characters. */
florian19f91bb2012-11-10 22:29:54 +0000219 HChar* name; /* NULL for NoName and DotDotDot */
sewardjb5f6f512005-03-10 23:59:00 +0000220 }
221 SuppLoc;
222
nethercote4a184902004-08-02 12:21:09 +0000223/* Suppressions. Tools can get/set tool-relevant parts with functions
njnc7561b92005-06-19 01:24:32 +0000224 declared in include/pub_tool_errormgr.h. Extensible via the 'extra' field.
nethercote4a184902004-08-02 12:21:09 +0000225 Tools can use a normal enum (with element values in the normal range
njn02bc4b82005-05-15 17:28:26 +0000226 (0..)) for 'skind'. */
nethercote4a184902004-08-02 12:21:09 +0000227struct _Supp {
228 struct _Supp* next;
229 Int count; // The number of times this error has been suppressed.
florian19f91bb2012-11-10 22:29:54 +0000230 HChar* sname; // The name by which the suppression is referred to.
sewardjb5f6f512005-03-10 23:59:00 +0000231
philippe362441d2013-07-22 22:00:13 +0000232 // Index in VG_(clo_suppressions) giving filename from which suppression
233 // was read, and the lineno in this file where sname was read.
234 Int clo_suppressions_i;
235 Int sname_lineno;
236
sewardjb5f6f512005-03-10 23:59:00 +0000237 // Length of 'callers'
238 Int n_callers;
239 // Array of callers, for matching stack traces. First one (name of fn
240 // where err occurs) is mandatory; rest are optional.
241 SuppLoc* callers;
nethercote4a184902004-08-02 12:21:09 +0000242
243 /* The tool-specific part */
244 SuppKind skind; // What kind of suppression. Must use the range (0..).
florian19f91bb2012-11-10 22:29:54 +0000245 HChar* string; // String -- use is optional. NULL by default.
nethercote4a184902004-08-02 12:21:09 +0000246 void* extra; // Anything else -- use is optional. NULL by default.
247};
248
249SuppKind VG_(get_supp_kind) ( Supp* su )
250{
251 return su->skind;
252}
253
florian19f91bb2012-11-10 22:29:54 +0000254HChar* VG_(get_supp_string) ( Supp* su )
nethercote4a184902004-08-02 12:21:09 +0000255{
256 return su->string;
257}
258
259void* VG_(get_supp_extra) ( Supp* su )
260{
261 return su->extra;
262}
263
264
265void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
266{
267 su->skind = skind;
268}
269
florian19f91bb2012-11-10 22:29:54 +0000270void VG_(set_supp_string) ( Supp* su, HChar* string )
nethercote4a184902004-08-02 12:21:09 +0000271{
272 su->string = string;
273}
274
275void VG_(set_supp_extra) ( Supp* su, void* extra )
276{
277 su->extra = extra;
278}
279
280
281/*------------------------------------------------------------*/
sewardjde4a1d02002-03-22 01:27:54 +0000282/*--- Helper fns ---*/
283/*------------------------------------------------------------*/
284
njn0087c502005-07-01 04:15:36 +0000285// Only show core errors if the tool wants to, we're not running with -q,
286// and were not outputting XML.
287Bool VG_(showing_core_errors)(void)
288{
289 return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
290}
291
sewardj738856f2009-07-15 14:48:32 +0000292/* Compare errors, to detect duplicates.
293*/
njn810086f2002-11-14 12:42:47 +0000294static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
sewardjde4a1d02002-03-22 01:27:54 +0000295{
njn810086f2002-11-14 12:42:47 +0000296 if (e1->ekind != e2->ekind)
sewardjde4a1d02002-03-22 01:27:54 +0000297 return False;
njn25e49d8e72002-09-23 09:36:25 +0000298 if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
sewardjde4a1d02002-03-22 01:27:54 +0000299 return False;
300
njn810086f2002-11-14 12:42:47 +0000301 switch (e1->ekind) {
njna86f29e2006-12-14 02:55:58 +0000302 //(example code, see comment on CoreSuppKind above)
303 //case ThreadErr:
304 // vg_assert(VG_(needs).core_errors);
305 // return <something>
sewardjde4a1d02002-03-22 01:27:54 +0000306 default:
njn51d827b2005-05-09 01:02:08 +0000307 if (VG_(needs).tool_errors) {
308 return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
309 } else {
njn95ec8702004-11-22 16:46:13 +0000310 VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
njn25e49d8e72002-09-23 09:36:25 +0000311 "probably needs to be set.\n",
njn810086f2002-11-14 12:42:47 +0000312 e1->ekind);
njn67993252004-11-22 18:02:32 +0000313 VG_(tool_panic)("unhandled error type");
njn25e49d8e72002-09-23 09:36:25 +0000314 }
sewardjde4a1d02002-03-22 01:27:54 +0000315 }
316}
317
sewardj738856f2009-07-15 14:48:32 +0000318
sewardj588adef2009-08-15 22:41:51 +0000319/* Helper functions for suppression generation: print a single line of
320 a suppression pseudo-stack-trace, either in XML or text mode. It's
321 important that the behaviour of these two functions exactly
322 corresponds.
sewardj738856f2009-07-15 14:48:32 +0000323*/
324#define ERRTXT_LEN 4096
325
sewardj588adef2009-08-15 22:41:51 +0000326static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
sewardjde4a1d02002-03-22 01:27:54 +0000327{
florian19f91bb2012-11-10 22:29:54 +0000328 static HChar buf[ERRTXT_LEN];
philippea0a73932014-06-15 15:42:20 +0000329 InlIPCursor* iipc = VG_(new_IIPC)(ip);
330 do {
331 if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN, iipc) ) {
332 VG_(printf_xml)(" <sframe> <fun>%pS</fun> </sframe>\n", buf);
333 } else
334 if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
335 VG_(printf_xml)(" <sframe> <obj>%pS</obj> </sframe>\n", buf);
336 } else {
337 VG_(printf_xml)(" <sframe> <obj>*</obj> </sframe>\n");
338 }
339 } while (VG_(next_IIPC)(iipc));
340 VG_(delete_IIPC)(iipc);
sewardjde4a1d02002-03-22 01:27:54 +0000341}
342
sewardj588adef2009-08-15 22:41:51 +0000343static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
344{
florian19f91bb2012-11-10 22:29:54 +0000345 static HChar buf[ERRTXT_LEN];
sewardj588adef2009-08-15 22:41:51 +0000346 XArray* /* of HChar */ text = (XArray*)textV;
philippea0a73932014-06-15 15:42:20 +0000347 InlIPCursor* iipc = VG_(new_IIPC)(ip);
348 do {
349 if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN, iipc) ) {
350 VG_(xaprintf)(text, " fun:%s\n", buf);
351 } else
352 if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
353 VG_(xaprintf)(text, " obj:%s\n", buf);
354 } else {
355 VG_(xaprintf)(text, " obj:*\n");
356 }
357 } while (VG_(next_IIPC)(iipc));
358 VG_(delete_IIPC)(iipc);
sewardj588adef2009-08-15 22:41:51 +0000359}
sewardj738856f2009-07-15 14:48:32 +0000360
361/* Generate a suppression for an error, either in text or XML mode.
362*/
363static void gen_suppression(Error* err)
364{
florian54fe2022012-10-27 23:07:42 +0000365 HChar xtra[256]; /* assumed big enough (is overrun-safe) */
sewardj588adef2009-08-15 22:41:51 +0000366 Bool anyXtra;
floriandbb35842012-10-27 18:39:11 +0000367 const HChar* name;
sewardj588adef2009-08-15 22:41:51 +0000368 ExeContext* ec;
369 XArray* /* HChar */ text;
sewardj738856f2009-07-15 14:48:32 +0000370
sewardj588adef2009-08-15 22:41:51 +0000371 const HChar* dummy_name = "insert_a_suppression_name_here";
sewardj738856f2009-07-15 14:48:32 +0000372
sewardj588adef2009-08-15 22:41:51 +0000373 vg_assert(err);
374
sewardj588adef2009-08-15 22:41:51 +0000375 ec = VG_(get_error_where)(err);
376 vg_assert(ec);
377
378 name = VG_TDICT_CALL(tool_get_error_name, err);
379 if (NULL == name) {
380 VG_(umsg)("(%s does not allow error to be suppressed)\n",
381 VG_(details).name);
382 return;
sewardj738856f2009-07-15 14:48:32 +0000383 }
384
tom7420e0a2011-07-06 14:08:24 +0000385 /* In XML mode, we also need to print the plain text version of the
386 suppresion in a CDATA section. What that really means is, we
387 need to generate the plaintext version both in XML and text
388 mode. So generate it into TEXT. */
389 text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
390 VG_(free), sizeof(HChar) );
391 vg_assert(text);
392
sewardj588adef2009-08-15 22:41:51 +0000393 /* Ok. Generate the plain text version into TEXT. */
394 VG_(xaprintf)(text, "{\n");
395 VG_(xaprintf)(text, " <%s>\n", dummy_name);
396 VG_(xaprintf)(text, " %s:%s\n", VG_(details).name, name);
397
398 VG_(memset)(xtra, 0, sizeof(xtra));
399 anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
400 err, xtra, sizeof(xtra));
401 vg_assert(xtra[sizeof(xtra)-1] == 0);
402
403 if (anyXtra)
404 VG_(xaprintf)(text, " %s\n", xtra);
405
sewardj738856f2009-07-15 14:48:32 +0000406 // Print stack trace elements
sewardj2f340eb2011-01-28 00:44:52 +0000407 UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
408 tl_assert(n_ips > 0);
409 if (n_ips > VG_MAX_SUPP_CALLERS)
410 n_ips = VG_MAX_SUPP_CALLERS;
sewardj588adef2009-08-15 22:41:51 +0000411 VG_(apply_StackTrace)(printSuppForIp_nonXML,
412 text,
sewardj738856f2009-07-15 14:48:32 +0000413 VG_(get_ExeContext_StackTrace)(ec),
sewardj2f340eb2011-01-28 00:44:52 +0000414 n_ips);
sewardj738856f2009-07-15 14:48:32 +0000415
sewardj588adef2009-08-15 22:41:51 +0000416 VG_(xaprintf)(text, "}\n");
417 // zero terminate
418 VG_(xaprintf)(text, "%c", (HChar)0 );
419 // VG_(printf) of text
420
421 /* And now display it. */
422 if (! VG_(clo_xml) ) {
423
424 // the simple case
425 VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
426
sewardj738856f2009-07-15 14:48:32 +0000427 } else {
sewardj588adef2009-08-15 22:41:51 +0000428
429 /* Now we have to print the XML directly. No need to go to the
430 effort of stuffing it in an XArray, since we won't need it
431 again. */
432 VG_(printf_xml)(" <suppression>\n");
433 VG_(printf_xml)(" <sname>%s</sname>\n", dummy_name);
bartb3af9cf2011-10-06 19:08:37 +0000434 VG_(printf_xml)(
435 " <skind>%pS:%pS</skind>\n", VG_(details).name, name);
sewardj588adef2009-08-15 22:41:51 +0000436 if (anyXtra)
bartb3af9cf2011-10-06 19:08:37 +0000437 VG_(printf_xml)(" <skaux>%pS</skaux>\n", xtra);
sewardj588adef2009-08-15 22:41:51 +0000438
439 // Print stack trace elements
440 VG_(apply_StackTrace)(printSuppForIp_XML,
441 NULL,
442 VG_(get_ExeContext_StackTrace)(ec),
443 VG_(get_ExeContext_n_ips)(ec));
444
445 // And now the cdata bit
446 // XXX FIXME! properly handle the case where the raw text
447 // itself contains "]]>", as specified in Protocol 4.
448 VG_(printf_xml)(" <rawtext>\n");
449 VG_(printf_xml)("<![CDATA[\n");
sewardjde78f9a2009-08-15 23:33:04 +0000450 VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
sewardj588adef2009-08-15 22:41:51 +0000451 VG_(printf_xml)("]]>\n");
452 VG_(printf_xml)(" </rawtext>\n");
453 VG_(printf_xml)(" </suppression>\n");
454
sewardj738856f2009-07-15 14:48:32 +0000455 }
sewardj588adef2009-08-15 22:41:51 +0000456
457 VG_(deleteXA)(text);
sewardj738856f2009-07-15 14:48:32 +0000458}
459
460
461/* Figure out if we want to perform a given action for this error,
462 possibly by asking the user.
463*/
florian2b8059a2012-10-14 16:45:23 +0000464Bool VG_(is_action_requested) ( const HChar* action, Bool* clo )
sewardjde4a1d02002-03-22 01:27:54 +0000465{
florian19f91bb2012-11-10 22:29:54 +0000466 HChar ch, ch2;
sewardjde4a1d02002-03-22 01:27:54 +0000467 Int res;
468
sewardj738856f2009-07-15 14:48:32 +0000469 /* First off, we shouldn't be asking the user anything if
470 we're in XML mode. */
471 if (VG_(clo_xml))
472 return False; /* That's a Nein, oder Nay as they say down here in B-W */
473
njn43c799e2003-04-08 00:08:52 +0000474 if (*clo == False)
sewardjde4a1d02002-03-22 01:27:54 +0000475 return False;
476
sewardj738856f2009-07-15 14:48:32 +0000477 VG_(umsg)("\n");
sewardjde4a1d02002-03-22 01:27:54 +0000478
479 again:
480 VG_(printf)(
481 "==%d== "
njn43c799e2003-04-08 00:08:52 +0000482 "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",
483 VG_(getpid)(), action
sewardjde4a1d02002-03-22 01:27:54 +0000484 );
485
sewardj6024b212003-07-13 10:54:33 +0000486 res = VG_(read)(VG_(clo_input_fd), &ch, 1);
sewardjde4a1d02002-03-22 01:27:54 +0000487 if (res != 1) goto ioerror;
488 /* res == 1 */
489 if (ch == '\n') return False;
490 if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y'
491 && ch != 'C' && ch != 'c') goto again;
492
sewardj6024b212003-07-13 10:54:33 +0000493 res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
sewardjde4a1d02002-03-22 01:27:54 +0000494 if (res != 1) goto ioerror;
495 if (ch2 != '\n') goto again;
496
njn43c799e2003-04-08 00:08:52 +0000497 /* No, don't want to do action. */
sewardjde4a1d02002-03-22 01:27:54 +0000498 if (ch == 'n' || ch == 'N') return False;
njn43c799e2003-04-08 00:08:52 +0000499 /* Yes, want to do action. */
sewardjde4a1d02002-03-22 01:27:54 +0000500 if (ch == 'y' || ch == 'Y') return True;
njn43c799e2003-04-08 00:08:52 +0000501 /* No, don't want to do action, and don't ask again either. */
sewardjde4a1d02002-03-22 01:27:54 +0000502 vg_assert(ch == 'c' || ch == 'C');
503
504 ioerror:
njn43c799e2003-04-08 00:08:52 +0000505 *clo = False;
sewardjde4a1d02002-03-22 01:27:54 +0000506 return False;
507}
508
509
sewardj738856f2009-07-15 14:48:32 +0000510/* Do text-mode actions on error, that is, immediately after an error
511 is printed. These are:
512 * possibly, attach to a debugger
513 * possibly, generate a suppression.
514 Note this should not be called in XML mode!
515*/
516static
517void do_actions_on_error(Error* err, Bool allow_db_attach)
518{
519 Bool still_noisy = True;
520
521 /* Should be assured by caller */
522 vg_assert( ! VG_(clo_xml) );
523
sewardj3b290482011-05-06 21:02:55 +0000524 /* if user wants to debug from a certain error nr, then wait for gdb/vgdb */
525 if (VG_(clo_vgdb) != Vg_VgdbNo
526 && allow_db_attach
philippebaf69642012-02-15 22:29:30 +0000527 && VG_(dyn_vgdb_error) <= n_errs_shown) {
sewardj3b290482011-05-06 21:02:55 +0000528 VG_(umsg)("(action on error) vgdb me ... \n");
529 VG_(gdbserver)( err->tid );
530 VG_(umsg)("Continuing ...\n");
531 }
532
sewardj738856f2009-07-15 14:48:32 +0000533 /* Perhaps we want a debugger attach at this point? */
sewardj3b290482011-05-06 21:02:55 +0000534 /* GDBTD ??? maybe we should/could remove the below assuming the
535 gdbserver interface is better ??? */
sewardj738856f2009-07-15 14:48:32 +0000536 if (allow_db_attach &&
537 VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
538 {
539 if (0) VG_(printf)("starting debugger\n");
540 VG_(start_debugger)( err->tid );
541 }
542 /* Or maybe we want to generate the error's suppression? */
543 if (VG_(clo_gen_suppressions) == 2
544 || (VG_(clo_gen_suppressions) == 1
545 && VG_(is_action_requested)( "Print suppression", &still_noisy ))
546 ) {
547 gen_suppression(err);
548 }
549 if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
550 VG_(clo_gen_suppressions) = 0;
551}
552
553
554/* Prints an error. Not entirely simple because of the differences
555 between XML and text mode output.
556
557 In XML mode:
558
559 * calls the tool's pre-show method, so the tool can create any
560 preamble ahead of the message, if it wants.
561
562 * prints the opening tag, and the <unique> and <tid> fields
563
564 * prints the tool-specific parts of the message
565
566 * if suppression generation is required, a suppression
567
568 * the closing tag
569
570 In text mode:
571
572 * calls the tool's pre-show method, so the tool can create any
573 preamble ahead of the message, if it wants.
574
575 * prints the tool-specific parts of the message
576
577 * calls do_actions_on_error. This optionally does a debugger
578 attach (and detach), and optionally prints a suppression; both
579 of these may require user input.
580*/
sewardj3b290482011-05-06 21:02:55 +0000581static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
sewardj738856f2009-07-15 14:48:32 +0000582{
583 /* If this fails, you probably specified your tool's method
584 dictionary incorrectly. */
585 vg_assert(VG_(needs).tool_errors);
586
sewardj3b290482011-05-06 21:02:55 +0000587 if (xml) {
sewardj738856f2009-07-15 14:48:32 +0000588
589 /* Note, allow_db_attach is ignored in here. */
590
591 /* Ensure that suppression generation is either completely
592 enabled or completely disabled; either way, we won't require
593 any user input. m_main.process_cmd_line_options should
594 ensure the asserted condition holds. */
595 vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
596 || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
597
598 /* Pre-show it to the tool */
599 VG_TDICT_CALL( tool_before_pp_Error, err );
600
601 /* standard preamble */
602 VG_(printf_xml)("<error>\n");
603 VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
604 VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
florian49789512013-09-16 17:08:50 +0000605 ThreadState* tst = VG_(get_ThreadState)(err->tid);
606 if (tst->thread_name) {
607 VG_(printf_xml)(" <threadname>%s</threadname>\n", tst->thread_name);
608 }
sewardj738856f2009-07-15 14:48:32 +0000609
610 /* actually print it */
611 VG_TDICT_CALL( tool_pp_Error, err );
612
613 if (VG_(clo_gen_suppressions) > 0)
614 gen_suppression(err);
615
616 /* postamble */
617 VG_(printf_xml)("</error>\n");
njnb6267bd2009-08-12 00:14:16 +0000618 VG_(printf_xml)("\n");
sewardj738856f2009-07-15 14:48:32 +0000619
620 } else {
621
622 VG_TDICT_CALL( tool_before_pp_Error, err );
623
624 if (VG_(tdict).tool_show_ThreadIDs_for_errors
625 && err->tid > 0 && err->tid != last_tid_printed) {
florian49789512013-09-16 17:08:50 +0000626 ThreadState* tst = VG_(get_ThreadState)(err->tid);
627 if (tst->thread_name) {
628 VG_(umsg)("Thread %d %s:\n", err->tid, tst->thread_name );
629 } else {
630 VG_(umsg)("Thread %d:\n", err->tid );
631 }
sewardj738856f2009-07-15 14:48:32 +0000632 last_tid_printed = err->tid;
633 }
634
635 VG_TDICT_CALL( tool_pp_Error, err );
njnb6267bd2009-08-12 00:14:16 +0000636 VG_(umsg)("\n");
sewardj738856f2009-07-15 14:48:32 +0000637
638 do_actions_on_error(err, allow_db_attach);
sewardj738856f2009-07-15 14:48:32 +0000639 }
640}
641
642
sewardjb5f6f512005-03-10 23:59:00 +0000643/* Construct an error */
sewardj738856f2009-07-15 14:48:32 +0000644static
njn72718642003-07-24 08:45:32 +0000645void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
floriane543f302012-10-21 19:43:43 +0000646 const HChar* s, void* extra, ExeContext* where )
sewardjde4a1d02002-03-22 01:27:54 +0000647{
sewardjdbada272005-07-02 21:16:30 +0000648 /* DO NOT MAKE unique_counter NON-STATIC */
649 static UInt unique_counter = 0;
650
njnca82cc02004-11-22 17:18:48 +0000651 tl_assert(tid < VG_N_THREADS);
njn72718642003-07-24 08:45:32 +0000652
njn810086f2002-11-14 12:42:47 +0000653 /* Core-only parts */
sewardjdbada272005-07-02 21:16:30 +0000654 err->unique = unique_counter++;
njn25e49d8e72002-09-23 09:36:25 +0000655 err->next = NULL;
656 err->supp = NULL;
657 err->count = 1;
njn72718642003-07-24 08:45:32 +0000658 err->tid = tid;
njn43c799e2003-04-08 00:08:52 +0000659 if (NULL == where)
sewardjadb102f2007-11-09 23:21:44 +0000660 err->where = VG_(record_ExeContext)( tid, 0 );
njn43c799e2003-04-08 00:08:52 +0000661 else
662 err->where = where;
njn1d6c4bc2002-11-21 13:38:08 +0000663
nethercote996901a2004-08-03 13:29:09 +0000664 /* Tool-relevant parts */
njn810086f2002-11-14 12:42:47 +0000665 err->ekind = ekind;
666 err->addr = a;
njn810086f2002-11-14 12:42:47 +0000667 err->extra = extra;
sewardja6022612003-07-24 23:50:17 +0000668 err->string = s;
669
njn25e49d8e72002-09-23 09:36:25 +0000670 /* sanity... */
njn72718642003-07-24 08:45:32 +0000671 vg_assert( tid < VG_N_THREADS );
njn25e49d8e72002-09-23 09:36:25 +0000672}
673
njn83f9e792005-06-11 05:04:09 +0000674
njn43c799e2003-04-08 00:08:52 +0000675
njn25e49d8e72002-09-23 09:36:25 +0000676/* Top-level entry point to the error management subsystem.
677 All detected errors are notified here; this routine decides if/when the
678 user should see the error. */
njn72718642003-07-24 08:45:32 +0000679void VG_(maybe_record_error) ( ThreadId tid,
floriane543f302012-10-21 19:43:43 +0000680 ErrorKind ekind, Addr a, const HChar* s, void* extra )
njn25e49d8e72002-09-23 09:36:25 +0000681{
njn810086f2002-11-14 12:42:47 +0000682 Error err;
683 Error* p;
684 Error* p_prev;
njn43c799e2003-04-08 00:08:52 +0000685 UInt extra_size;
njn695c16e2005-03-27 03:40:28 +0000686 VgRes exe_res = Vg_MedRes;
687 static Bool stopping_message = False;
688 static Bool slowdown_message = False;
sewardjde4a1d02002-03-22 01:27:54 +0000689
njn14319cc2005-03-13 06:26:22 +0000690 /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
691 been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
sewardjf2537be2002-04-24 21:03:47 +0000692 have been found, just refuse to collect any more. This stops
693 the burden of the error-management system becoming excessive in
694 extremely buggy programs, although it does make it pretty
695 pointless to continue the Valgrind run after this point. */
sewardj2e432902002-06-13 20:44:00 +0000696 if (VG_(clo_error_limit)
njn695c16e2005-03-27 03:40:28 +0000697 && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
sewardj8a051722005-06-30 00:10:16 +0000698 || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
699 && !VG_(clo_xml)) {
sewardjde4a1d02002-03-22 01:27:54 +0000700 if (!stopping_message) {
sewardj738856f2009-07-15 14:48:32 +0000701 VG_(umsg)("\n");
sewardjf2537be2002-04-24 21:03:47 +0000702
njn695c16e2005-03-27 03:40:28 +0000703 if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
sewardj738856f2009-07-15 14:48:32 +0000704 VG_(umsg)(
sewardjf2537be2002-04-24 21:03:47 +0000705 "More than %d different errors detected. "
sewardj738856f2009-07-15 14:48:32 +0000706 "I'm not reporting any more.\n",
njn14319cc2005-03-13 06:26:22 +0000707 M_COLLECT_NO_ERRORS_AFTER_SHOWN );
sewardjf2537be2002-04-24 21:03:47 +0000708 } else {
sewardj738856f2009-07-15 14:48:32 +0000709 VG_(umsg)(
sewardjf2537be2002-04-24 21:03:47 +0000710 "More than %d total errors detected. "
sewardj738856f2009-07-15 14:48:32 +0000711 "I'm not reporting any more.\n",
njn14319cc2005-03-13 06:26:22 +0000712 M_COLLECT_NO_ERRORS_AFTER_FOUND );
sewardjf2537be2002-04-24 21:03:47 +0000713 }
714
sewardj738856f2009-07-15 14:48:32 +0000715 VG_(umsg)("Final error counts will be inaccurate. "
716 "Go fix your program!\n");
717 VG_(umsg)("Rerun with --error-limit=no to disable "
718 "this cutoff. Note\n");
719 VG_(umsg)("that errors may occur in your program without "
720 "prior warning from\n");
721 VG_(umsg)("Valgrind, because errors are no longer "
722 "being displayed.\n");
723 VG_(umsg)("\n");
sewardjde4a1d02002-03-22 01:27:54 +0000724 stopping_message = True;
725 }
726 return;
727 }
728
sewardjdc873c02011-07-24 16:02:33 +0000729 /* Ignore it if error acquisition is disabled for this thread. */
730 { ThreadState* tst = VG_(get_ThreadState)(tid);
731 if (tst->err_disablement_level > 0)
732 return;
733 }
734
njn14319cc2005-03-13 06:26:22 +0000735 /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
sewardjde4a1d02002-03-22 01:27:54 +0000736 been found, be much more conservative about collecting new
737 ones. */
sewardj8a051722005-06-30 00:10:16 +0000738 if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
739 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000740 exe_res = Vg_LowRes;
sewardjde4a1d02002-03-22 01:27:54 +0000741 if (!slowdown_message) {
sewardj738856f2009-07-15 14:48:32 +0000742 VG_(umsg)("\n");
743 VG_(umsg)("More than %d errors detected. Subsequent errors\n",
744 M_COLLECT_ERRORS_SLOWLY_AFTER);
745 VG_(umsg)("will still be recorded, but in less "
746 "detail than before.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000747 slowdown_message = True;
748 }
749 }
750
njn25e49d8e72002-09-23 09:36:25 +0000751 /* Build ourselves the error */
njn72718642003-07-24 08:45:32 +0000752 construct_error ( &err, tid, ekind, a, s, extra, NULL );
sewardjde4a1d02002-03-22 01:27:54 +0000753
754 /* First, see if we've got an error record matching this one. */
sewardj8a7d4e42006-10-17 01:41:17 +0000755 em_errlist_searches++;
756 p = errors;
757 p_prev = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000758 while (p != NULL) {
sewardj8a7d4e42006-10-17 01:41:17 +0000759 em_errlist_cmps++;
njn810086f2002-11-14 12:42:47 +0000760 if (eq_Error(exe_res, p, &err)) {
sewardjde4a1d02002-03-22 01:27:54 +0000761 /* Found it. */
762 p->count++;
763 if (p->supp != NULL) {
764 /* Deal correctly with suppressed errors. */
765 p->supp->count++;
nethercotef2b11482004-08-02 12:36:01 +0000766 n_errs_suppressed++;
sewardjde4a1d02002-03-22 01:27:54 +0000767 } else {
nethercotef2b11482004-08-02 12:36:01 +0000768 n_errs_found++;
sewardjde4a1d02002-03-22 01:27:54 +0000769 }
770
771 /* Move p to the front of the list so that future searches
sewardj3b290482011-05-06 21:02:55 +0000772 for it are faster. It also allows to print the last
773 error (see VG_(show_last_error). */
sewardjde4a1d02002-03-22 01:27:54 +0000774 if (p_prev != NULL) {
775 vg_assert(p_prev->next == p);
njn695c16e2005-03-27 03:40:28 +0000776 p_prev->next = p->next;
777 p->next = errors;
778 errors = p;
sewardjde4a1d02002-03-22 01:27:54 +0000779 }
sewardj7ebf7c32003-07-24 21:29:40 +0000780
sewardjde4a1d02002-03-22 01:27:54 +0000781 return;
782 }
783 p_prev = p;
784 p = p->next;
785 }
786
787 /* Didn't see it. Copy and add. */
788
njn43c799e2003-04-08 00:08:52 +0000789 /* OK, we're really going to collect it. The context is on the stack and
790 will disappear shortly, so we must copy it. First do the main
njn02bc4b82005-05-15 17:28:26 +0000791 (non-'extra') part.
njn25e49d8e72002-09-23 09:36:25 +0000792
njn02bc4b82005-05-15 17:28:26 +0000793 Then VG_(tdict).tool_update_extra can update the 'extra' part. This
njn51d827b2005-05-09 01:02:08 +0000794 is for when there are more details to fill in which take time to work
795 out but don't affect our earlier decision to include the error -- by
njn25e49d8e72002-09-23 09:36:25 +0000796 postponing those details until now, we avoid the extra work in the
njn810086f2002-11-14 12:42:47 +0000797 case where we ignore the error. Ugly.
njn43c799e2003-04-08 00:08:52 +0000798
njn02bc4b82005-05-15 17:28:26 +0000799 Then, if there is an 'extra' part, copy it too, using the size that
njn51d827b2005-05-09 01:02:08 +0000800 VG_(tdict).tool_update_extra returned. Also allow for people using
801 the void* extra field for a scalar value like an integer.
njn43c799e2003-04-08 00:08:52 +0000802 */
803
804 /* copy main part */
floriana2968cc2013-09-20 21:34:40 +0000805 p = VG_(malloc)("errormgr.mre.1", sizeof(Error));
njn25e49d8e72002-09-23 09:36:25 +0000806 *p = err;
njn43c799e2003-04-08 00:08:52 +0000807
njn02bc4b82005-05-15 17:28:26 +0000808 /* update 'extra' */
sewardjb5f6f512005-03-10 23:59:00 +0000809 switch (ekind) {
njna86f29e2006-12-14 02:55:58 +0000810 //(example code, see comment on CoreSuppKind above)
811 //case ThreadErr:
812 // vg_assert(VG_(needs).core_errors);
813 // extra_size = <something>
814 // break;
sewardjb5f6f512005-03-10 23:59:00 +0000815 default:
816 vg_assert(VG_(needs).tool_errors);
njn51d827b2005-05-09 01:02:08 +0000817 extra_size = VG_TDICT_CALL(tool_update_extra, p);
sewardjb5f6f512005-03-10 23:59:00 +0000818 break;
819 }
njn43c799e2003-04-08 00:08:52 +0000820
njn02bc4b82005-05-15 17:28:26 +0000821 /* copy block pointed to by 'extra', if there is one */
sewardjb5f6f512005-03-10 23:59:00 +0000822 if (NULL != p->extra && 0 != extra_size) {
sewardj9c606bd2008-09-18 18:12:50 +0000823 void* new_extra = VG_(malloc)("errormgr.mre.2", extra_size);
sewardjb5f6f512005-03-10 23:59:00 +0000824 VG_(memcpy)(new_extra, p->extra, extra_size);
825 p->extra = new_extra;
njn43c799e2003-04-08 00:08:52 +0000826 }
827
njn695c16e2005-03-27 03:40:28 +0000828 p->next = errors;
njn25e49d8e72002-09-23 09:36:25 +0000829 p->supp = is_suppressible_error(&err);
njn695c16e2005-03-27 03:40:28 +0000830 errors = p;
sewardjde4a1d02002-03-22 01:27:54 +0000831 if (p->supp == NULL) {
philippebaf69642012-02-15 22:29:30 +0000832 /* update stats */
njn606a4ae2009-08-11 00:52:40 +0000833 n_err_contexts++;
nethercotef2b11482004-08-02 12:36:01 +0000834 n_errs_found++;
philippebaf69642012-02-15 22:29:30 +0000835 n_errs_shown++;
sewardj738856f2009-07-15 14:48:32 +0000836 /* Actually show the error; more complex than you might think. */
sewardj3b290482011-05-06 21:02:55 +0000837 pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
sewardjde4a1d02002-03-22 01:27:54 +0000838 } else {
njn606a4ae2009-08-11 00:52:40 +0000839 n_supp_contexts++;
nethercotef2b11482004-08-02 12:36:01 +0000840 n_errs_suppressed++;
sewardjde4a1d02002-03-22 01:27:54 +0000841 p->supp->count++;
842 }
843}
844
njn43c799e2003-04-08 00:08:52 +0000845/* Second top-level entry point to the error management subsystem, for
nethercote7cc9c232004-01-21 15:08:04 +0000846 errors that the tool wants to report immediately, eg. because they're
njn43c799e2003-04-08 00:08:52 +0000847 guaranteed to only happen once. This avoids all the recording and
848 comparing stuff. But they can be suppressed; returns True if it is
njn02bc4b82005-05-15 17:28:26 +0000849 suppressed. Bool 'print_error' dictates whether to print the error.
njn18afe5d2009-08-10 08:25:39 +0000850 Bool 'count_error' dictates whether to count the error in n_errs_found.
njn47363ab2003-04-21 13:24:40 +0000851*/
floriane543f302012-10-21 19:43:43 +0000852Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, const HChar* s,
njn3e884182003-04-15 13:03:23 +0000853 void* extra, ExeContext* where, Bool print_error,
njn18afe5d2009-08-10 08:25:39 +0000854 Bool allow_db_attach, Bool count_error )
njn43c799e2003-04-08 00:08:52 +0000855{
njnfb289bc2007-01-12 23:59:50 +0000856 Error err;
857 Supp *su;
njn43c799e2003-04-08 00:08:52 +0000858
sewardjdc873c02011-07-24 16:02:33 +0000859 /* Ignore it if error acquisition is disabled for this thread. */
860 ThreadState* tst = VG_(get_ThreadState)(tid);
861 if (tst->err_disablement_level > 0)
862 return False; /* ignored, not suppressed */
863
njn43c799e2003-04-08 00:08:52 +0000864 /* Build ourselves the error */
njn72718642003-07-24 08:45:32 +0000865 construct_error ( &err, tid, ekind, a, s, extra, where );
njn43c799e2003-04-08 00:08:52 +0000866
867 /* Unless it's suppressed, we're going to show it. Don't need to make
868 a copy, because it's only temporary anyway.
869
njn02bc4b82005-05-15 17:28:26 +0000870 Then update the 'extra' part with VG_(tdict).tool_update_extra),
njn51d827b2005-05-09 01:02:08 +0000871 because that can have an affect on whether it's suppressed. Ignore
872 the size return value of VG_(tdict).tool_update_extra, because we're
njn02bc4b82005-05-15 17:28:26 +0000873 not copying 'extra'. */
njn51d827b2005-05-09 01:02:08 +0000874 (void)VG_TDICT_CALL(tool_update_extra, &err);
njn43c799e2003-04-08 00:08:52 +0000875
njnfb289bc2007-01-12 23:59:50 +0000876 su = is_suppressible_error(&err);
877 if (NULL == su) {
njn606a4ae2009-08-11 00:52:40 +0000878 if (count_error) {
njn18afe5d2009-08-10 08:25:39 +0000879 n_errs_found++;
njn606a4ae2009-08-11 00:52:40 +0000880 n_err_contexts++;
881 }
njn43c799e2003-04-08 00:08:52 +0000882
883 if (print_error) {
sewardj738856f2009-07-15 14:48:32 +0000884 /* update stats */
njnfb289bc2007-01-12 23:59:50 +0000885 n_errs_shown++;
philippebaf69642012-02-15 22:29:30 +0000886 /* Actually show the error; more complex than you might think. */
887 pp_Error(&err, allow_db_attach, VG_(clo_xml));
njn43c799e2003-04-08 00:08:52 +0000888 }
njn43c799e2003-04-08 00:08:52 +0000889 return False;
890
891 } else {
njn663ab792009-08-13 04:24:38 +0000892 if (count_error) {
893 n_errs_suppressed++;
894 n_supp_contexts++;
895 }
njnfb289bc2007-01-12 23:59:50 +0000896 su->count++;
njn43c799e2003-04-08 00:08:52 +0000897 return True;
898 }
899}
900
sewardjde4a1d02002-03-22 01:27:54 +0000901
sewardjde4a1d02002-03-22 01:27:54 +0000902/*------------------------------------------------------------*/
903/*--- Exported fns ---*/
904/*------------------------------------------------------------*/
905
sewardj71bc3cb2005-05-19 00:25:45 +0000906/* Show the used suppressions. Returns False if no suppression
907 got used. */
908static Bool show_used_suppressions ( void )
909{
910 Supp *su;
911 Bool any_supp;
912
sewardj7c9e57c2005-05-24 14:21:45 +0000913 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000914 VG_(printf_xml)("<suppcounts>\n");
sewardj7c9e57c2005-05-24 14:21:45 +0000915
sewardj71bc3cb2005-05-19 00:25:45 +0000916 any_supp = False;
917 for (su = suppressions; su != NULL; su = su->next) {
918 if (su->count <= 0)
919 continue;
sewardj71bc3cb2005-05-19 00:25:45 +0000920 if (VG_(clo_xml)) {
bartb3af9cf2011-10-06 19:08:37 +0000921 VG_(printf_xml)( " <pair>\n"
sewardj738856f2009-07-15 14:48:32 +0000922 " <count>%d</count>\n"
bartb3af9cf2011-10-06 19:08:37 +0000923 " <name>%pS</name>\n"
sewardj738856f2009-07-15 14:48:32 +0000924 " </pair>\n",
925 su->count, su->sname );
sewardj71bc3cb2005-05-19 00:25:45 +0000926 } else {
philippe4e32d672013-10-17 22:10:41 +0000927 HChar xtra[256]; /* assumed big enough (is overrun-safe) */
928 Bool anyXtra;
sewardj2d9e8742009-08-07 15:46:56 +0000929 // blank line before the first shown suppression, if any
930 if (!any_supp)
931 VG_(dmsg)("\n");
philippe4e32d672013-10-17 22:10:41 +0000932 VG_(memset)(xtra, 0, sizeof(xtra));
933 anyXtra = VG_TDICT_CALL(tool_print_extra_suppression_use,
934 su, xtra, sizeof(xtra));
935 vg_assert(xtra[sizeof(xtra)-1] == 0);
936 VG_(dmsg)("used_suppression: %6d %s %s:%d%s%s\n", su->count, su->sname,
philippe362441d2013-07-22 22:00:13 +0000937 VG_(clo_suppressions)[su->clo_suppressions_i],
philippe4e32d672013-10-17 22:10:41 +0000938 su->sname_lineno,
939 anyXtra ? " " : "", xtra);
sewardj71bc3cb2005-05-19 00:25:45 +0000940 }
sewardj2d9e8742009-08-07 15:46:56 +0000941 any_supp = True;
sewardj71bc3cb2005-05-19 00:25:45 +0000942 }
943
sewardj7c9e57c2005-05-24 14:21:45 +0000944 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000945 VG_(printf_xml)("</suppcounts>\n");
sewardj7c9e57c2005-05-24 14:21:45 +0000946
sewardj71bc3cb2005-05-19 00:25:45 +0000947 return any_supp;
948}
949
sewardj9f297ca2005-05-20 02:29:52 +0000950/* Show all the errors that occurred, and possibly also the
951 suppressions used. */
sewardj3b290482011-05-06 21:02:55 +0000952void VG_(show_all_errors) ( Int verbosity, Bool xml )
sewardjde4a1d02002-03-22 01:27:54 +0000953{
njn810086f2002-11-14 12:42:47 +0000954 Int i, n_min;
njn810086f2002-11-14 12:42:47 +0000955 Error *p, *p_min;
njn810086f2002-11-14 12:42:47 +0000956 Bool any_supp;
sewardjde4a1d02002-03-22 01:27:54 +0000957
sewardj3b290482011-05-06 21:02:55 +0000958 if (verbosity == 0)
sewardjde4a1d02002-03-22 01:27:54 +0000959 return;
960
njn606a4ae2009-08-11 00:52:40 +0000961 /* If we're printing XML, just show the suppressions and stop. */
sewardj3b290482011-05-06 21:02:55 +0000962 if (xml) {
sewardj71bc3cb2005-05-19 00:25:45 +0000963 (void)show_used_suppressions();
964 return;
965 }
966
967 /* We only get here if not printing XML. */
sewardj738856f2009-07-15 14:48:32 +0000968 VG_(umsg)("ERROR SUMMARY: "
969 "%d errors from %d contexts (suppressed: %d from %d)\n",
970 n_errs_found, n_err_contexts,
971 n_errs_suppressed, n_supp_contexts );
sewardjde4a1d02002-03-22 01:27:54 +0000972
sewardj3b290482011-05-06 21:02:55 +0000973 if (verbosity <= 1)
sewardjde4a1d02002-03-22 01:27:54 +0000974 return;
975
sewardj2d9e8742009-08-07 15:46:56 +0000976 // We do the following only at -v or above, and only in non-XML
977 // mode
978
sewardj3b290482011-05-06 21:02:55 +0000979 /* Print the contexts in order of increasing error count.
980 Once an error is shown, we add a huge value to its count to filter it
philippe362441d2013-07-22 22:00:13 +0000981 out.
982 After having shown all errors, we reset count to the original value. */
sewardjde4a1d02002-03-22 01:27:54 +0000983 for (i = 0; i < n_err_contexts; i++) {
984 n_min = (1 << 30) - 1;
985 p_min = NULL;
njn695c16e2005-03-27 03:40:28 +0000986 for (p = errors; p != NULL; p = p->next) {
sewardjde4a1d02002-03-22 01:27:54 +0000987 if (p->supp != NULL) continue;
988 if (p->count < n_min) {
989 n_min = p->count;
990 p_min = p;
991 }
992 }
njn663ab792009-08-13 04:24:38 +0000993 // XXX: this isn't right. See bug 203651.
994 if (p_min == NULL) continue; //VG_(tool_panic)("show_all_errors()");
sewardjde4a1d02002-03-22 01:27:54 +0000995
sewardj738856f2009-07-15 14:48:32 +0000996 VG_(umsg)("\n");
997 VG_(umsg)("%d errors in context %d of %d:\n",
998 p_min->count, i+1, n_err_contexts);
sewardj3b290482011-05-06 21:02:55 +0000999 pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );
sewardj738856f2009-07-15 14:48:32 +00001000
1001 // We're not printing XML -- we'd have exited above if so.
sewardj3b290482011-05-06 21:02:55 +00001002 vg_assert(! xml);
sewardjde4a1d02002-03-22 01:27:54 +00001003
1004 if ((i+1 == VG_(clo_dump_error))) {
sewardj7cf4e6b2008-05-01 20:24:26 +00001005 StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
sewardjfa8ec112005-01-19 11:55:34 +00001006 VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
njn394213a2005-06-19 18:38:24 +00001007 ips[0], /*debugging*/True, 0xFE/*verbosity*/,
sewardj0ec07f32006-01-12 12:32:32 +00001008 /*bbs_done*/0,
1009 /*allow redir?*/True);
sewardjde4a1d02002-03-22 01:27:54 +00001010 }
1011
sewardj3b290482011-05-06 21:02:55 +00001012 p_min->count = p_min->count + (1 << 30);
sewardjde4a1d02002-03-22 01:27:54 +00001013 }
1014
sewardj3b290482011-05-06 21:02:55 +00001015 /* reset the counts, otherwise a 2nd call does not show anything anymore */
1016 for (p = errors; p != NULL; p = p->next) {
1017 if (p->count >= (1 << 30))
1018 p->count = p->count - (1 << 30);
1019 }
1020
1021
sewardj71bc3cb2005-05-19 00:25:45 +00001022 any_supp = show_used_suppressions();
sewardjde4a1d02002-03-22 01:27:54 +00001023
sewardj2d9e8742009-08-07 15:46:56 +00001024 if (any_supp)
sewardj738856f2009-07-15 14:48:32 +00001025 VG_(umsg)("\n");
sewardj2d9e8742009-08-07 15:46:56 +00001026 // reprint this, so users don't have to scroll way up to find
1027 // the first printing
1028 VG_(umsg)("ERROR SUMMARY: "
1029 "%d errors from %d contexts (suppressed: %d from %d)\n",
1030 n_errs_found, n_err_contexts, n_errs_suppressed,
1031 n_supp_contexts );
sewardjde4a1d02002-03-22 01:27:54 +00001032}
1033
sewardj3b290482011-05-06 21:02:55 +00001034void VG_(show_last_error) ( void )
1035{
1036 if (n_err_contexts == 0) {
1037 VG_(umsg)("No errors yet\n");
1038 return;
1039 }
1040
1041 pp_Error( errors, False/*allow_db_attach*/, False/*xml*/ );
1042}
1043
sewardj9f297ca2005-05-20 02:29:52 +00001044
1045/* Show occurrence counts of all errors, in XML form. */
1046void VG_(show_error_counts_as_XML) ( void )
1047{
1048 Error* err;
sewardj738856f2009-07-15 14:48:32 +00001049 VG_(printf_xml)("<errorcounts>\n");
sewardj9f297ca2005-05-20 02:29:52 +00001050 for (err = errors; err != NULL; err = err->next) {
1051 if (err->supp != NULL)
1052 continue;
1053 if (err->count <= 0)
1054 continue;
sewardj738856f2009-07-15 14:48:32 +00001055 VG_(printf_xml)(" <pair>\n");
1056 VG_(printf_xml)(" <count>%d</count>\n", err->count);
1057 VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
1058 VG_(printf_xml)(" </pair>\n");
sewardj9f297ca2005-05-20 02:29:52 +00001059 }
sewardj738856f2009-07-15 14:48:32 +00001060 VG_(printf_xml)("</errorcounts>\n");
njnb6267bd2009-08-12 00:14:16 +00001061 VG_(printf_xml)("\n");
sewardj9f297ca2005-05-20 02:29:52 +00001062}
1063
1064
sewardjde4a1d02002-03-22 01:27:54 +00001065/*------------------------------------------------------------*/
sewardjd7a02db2008-12-12 08:07:49 +00001066/*--- Suppression parsing ---*/
sewardjde4a1d02002-03-22 01:27:54 +00001067/*------------------------------------------------------------*/
1068
sewardj8a7d4e42006-10-17 01:41:17 +00001069/* Get the next char from fd into *out_buf. Returns 1 if success,
1070 0 if eof or < 0 if error. */
1071
florian19f91bb2012-11-10 22:29:54 +00001072static Int get_char ( Int fd, HChar* out_buf )
sewardj8a7d4e42006-10-17 01:41:17 +00001073{
1074 Int r;
florian19f91bb2012-11-10 22:29:54 +00001075 static HChar buf[256];
sewardj8a7d4e42006-10-17 01:41:17 +00001076 static Int buf_size = 0;
1077 static Int buf_used = 0;
sewardj89c5bd82008-10-23 10:15:37 +00001078 vg_assert(buf_size >= 0 && buf_size <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001079 vg_assert(buf_used >= 0 && buf_used <= buf_size);
1080 if (buf_used == buf_size) {
sewardj89c5bd82008-10-23 10:15:37 +00001081 r = VG_(read)(fd, buf, 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001082 if (r < 0) return r; /* read failed */
sewardj89c5bd82008-10-23 10:15:37 +00001083 vg_assert(r >= 0 && r <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001084 buf_size = r;
1085 buf_used = 0;
1086 }
1087 if (buf_size == 0)
1088 return 0; /* eof */
sewardj89c5bd82008-10-23 10:15:37 +00001089 vg_assert(buf_size >= 0 && buf_size <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001090 vg_assert(buf_used >= 0 && buf_used < buf_size);
1091 *out_buf = buf[buf_used];
1092 buf_used++;
1093 return 1;
1094}
1095
philippe2193a7c2012-12-08 17:54:16 +00001096// Get a non blank non comment line.
1097// Returns True if eof.
1098static Bool get_nbnc_line ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
sewardjde4a1d02002-03-22 01:27:54 +00001099{
florian19f91bb2012-11-10 22:29:54 +00001100 HChar* buf = *bufpp;
njn35db56c2009-07-24 07:38:29 +00001101 SizeT nBuf = *nBufp;
florian19f91bb2012-11-10 22:29:54 +00001102 HChar ch;
njn35db56c2009-07-24 07:38:29 +00001103 Int n, i;
philippe362441d2013-07-22 22:00:13 +00001104
1105 vg_assert(lineno); // lineno needed to correctly track line numbers.
1106
sewardjde4a1d02002-03-22 01:27:54 +00001107 while (True) {
philippe2193a7c2012-12-08 17:54:16 +00001108 buf[0] = 0;
sewardjde4a1d02002-03-22 01:27:54 +00001109 /* First, read until a non-blank char appears. */
1110 while (True) {
sewardj8a7d4e42006-10-17 01:41:17 +00001111 n = get_char(fd, &ch);
njn0c0f32a2005-03-26 04:14:01 +00001112 if (n == 1 && !VG_(isspace)(ch)) break;
bart050eec52009-07-27 12:03:03 +00001113 if (n == 1 && ch == '\n' && lineno)
1114 (*lineno)++;
sewardj8a7d4e42006-10-17 01:41:17 +00001115 if (n <= 0) return True;
sewardjde4a1d02002-03-22 01:27:54 +00001116 }
1117
1118 /* Now, read the line into buf. */
1119 i = 0;
1120 buf[i++] = ch; buf[i] = 0;
1121 while (True) {
sewardj8a7d4e42006-10-17 01:41:17 +00001122 n = get_char(fd, &ch);
1123 if (n <= 0) return False; /* the next call will return True */
bart050eec52009-07-27 12:03:03 +00001124 if (ch == '\n' && lineno)
1125 (*lineno)++;
sewardjde4a1d02002-03-22 01:27:54 +00001126 if (ch == '\n') break;
njn35db56c2009-07-24 07:38:29 +00001127 if (i > 0 && i == nBuf-1) {
1128 *nBufp = nBuf = nBuf * 2;
1129 #define RIDICULOUS 100000
1130 vg_assert2(nBuf < RIDICULOUS, // Just a sanity check, really.
1131 "VG_(get_line): line longer than %d chars, aborting\n",
1132 RIDICULOUS);
1133 *bufpp = buf = VG_(realloc)("errormgr.get_line.1", buf, nBuf);
1134 }
sewardjde4a1d02002-03-22 01:27:54 +00001135 buf[i++] = ch; buf[i] = 0;
1136 }
njn0c0f32a2005-03-26 04:14:01 +00001137 while (i > 1 && VG_(isspace)(buf[i-1])) {
sewardjde4a1d02002-03-22 01:27:54 +00001138 i--; buf[i] = 0;
1139 };
1140
philippe362441d2013-07-22 22:00:13 +00001141 // VG_(printf)("The line *%p %d is '%s'\n", lineno, *lineno, buf);
sewardjde4a1d02002-03-22 01:27:54 +00001142 /* Ok, we have a line. If a non-comment line, return.
1143 If a comment line, start all over again. */
1144 if (buf[0] != '#') return False;
1145 }
1146}
1147
philippe2193a7c2012-12-08 17:54:16 +00001148// True if buf starts with fun: or obj: or is ...
1149static Bool is_location_line (HChar* buf)
1150{
1151 return VG_(strncmp)(buf, "fun:", 4) == 0
1152 || VG_(strncmp)(buf, "obj:", 4) == 0
1153 || VG_(strcmp)(buf, "...") == 0;
1154}
1155
1156Bool VG_(get_line) ( Int fd, HChar** bufpp, SizeT* nBufp, Int* lineno )
1157{
1158 Bool eof = get_nbnc_line (fd, bufpp, nBufp, lineno);
1159
1160 if (eof)
1161 return True;
1162
1163 if (is_location_line(*bufpp))
1164 return True; // Not a extra suppr line
1165 else
philippe362441d2013-07-22 22:00:13 +00001166 return False; // A suppression extra line
philippe2193a7c2012-12-08 17:54:16 +00001167}
sewardjde4a1d02002-03-22 01:27:54 +00001168
philippe2c5c05e2012-07-26 21:37:36 +00001169/* True if s contains no wildcard (?, *) characters. */
florian19f91bb2012-11-10 22:29:54 +00001170static Bool is_simple_str (const HChar *s)
philippe2c5c05e2012-07-26 21:37:36 +00001171{
philippe2c5c05e2012-07-26 21:37:36 +00001172 while (*s) {
1173 if (*s == '?' || *s == '*')
1174 return False;
1175 s++;
1176 }
1177 return True;
1178}
1179
philippe7d69fd92012-02-26 21:26:00 +00001180/* buf contains the raw name of a caller, supposedly either
sewardjde4a1d02002-03-22 01:27:54 +00001181 fun:some_function_name or
philippe7d69fd92012-02-26 21:26:00 +00001182 obj:some_object_name or
1183 ...
1184 Set p->ty and p->name accordingly.
1185 p->name is allocated and set to the string
1186 after the descriptor (fun: or obj:) part.
sewardjde4a1d02002-03-22 01:27:54 +00001187 Returns False if failed.
1188*/
florian19f91bb2012-11-10 22:29:54 +00001189static Bool setLocationTy ( SuppLoc* p, HChar *buf )
sewardjde4a1d02002-03-22 01:27:54 +00001190{
philippe7d69fd92012-02-26 21:26:00 +00001191 if (VG_(strncmp)(buf, "fun:", 4) == 0) {
1192 p->name = VG_(arena_strdup)(VG_AR_CORE,
1193 "errormgr.sLTy.1", buf+4);
philippe2c5c05e2012-07-26 21:37:36 +00001194 p->name_is_simple_str = is_simple_str (p->name);
sewardjb5f6f512005-03-10 23:59:00 +00001195 p->ty = FunName;
sewardjde4a1d02002-03-22 01:27:54 +00001196 return True;
1197 }
philippe7d69fd92012-02-26 21:26:00 +00001198 if (VG_(strncmp)(buf, "obj:", 4) == 0) {
1199 p->name = VG_(arena_strdup)(VG_AR_CORE,
1200 "errormgr.sLTy.2", buf+4);
philippe2c5c05e2012-07-26 21:37:36 +00001201 p->name_is_simple_str = is_simple_str (p->name);
sewardjb5f6f512005-03-10 23:59:00 +00001202 p->ty = ObjName;
sewardjde4a1d02002-03-22 01:27:54 +00001203 return True;
1204 }
philippe7d69fd92012-02-26 21:26:00 +00001205 if (VG_(strcmp)(buf, "...") == 0) {
sewardj5e519302008-11-03 23:10:25 +00001206 p->name = NULL;
philippe2c5c05e2012-07-26 21:37:36 +00001207 p->name_is_simple_str = False;
sewardj5e519302008-11-03 23:10:25 +00001208 p->ty = DotDotDot;
1209 return True;
1210 }
1211 VG_(printf)("location should be \"...\", or should start "
1212 "with \"fun:\" or \"obj:\"\n");
sewardjde4a1d02002-03-22 01:27:54 +00001213 return False;
1214}
1215
1216
nethercote7cc9c232004-01-21 15:08:04 +00001217/* Look for "tool" in a string like "tool1,tool2,tool3" */
florian19f91bb2012-11-10 22:29:54 +00001218static Bool tool_name_present(const HChar *name, HChar *names)
njn11cc9252002-10-07 14:42:59 +00001219{
1220 Bool found;
florian19f91bb2012-11-10 22:29:54 +00001221 HChar *s = NULL; /* Shut gcc up */
njn11cc9252002-10-07 14:42:59 +00001222 Int len = VG_(strlen)(name);
1223
1224 found = (NULL != (s = VG_(strstr)(names, name)) &&
1225 (s == names || *(s-1) == ',') &&
1226 (*(s+len) == ',' || *(s+len) == '\0')
1227 );
1228
1229 return found;
1230}
1231
philippe362441d2013-07-22 22:00:13 +00001232/* Read suppressions from the file specified in
1233 VG_(clo_suppressions)[clo_suppressions_i]
sewardjde4a1d02002-03-22 01:27:54 +00001234 and place them in the suppressions list. If there's any difficulty
1235 doing this, just give up -- there's no point in trying to recover.
1236*/
philippe362441d2013-07-22 22:00:13 +00001237static void load_one_suppressions_file ( Int clo_suppressions_i )
sewardjde4a1d02002-03-22 01:27:54 +00001238{
philippe362441d2013-07-22 22:00:13 +00001239 const HChar* filename = VG_(clo_suppressions)[clo_suppressions_i];
sewardj92645592005-07-23 09:18:34 +00001240 SysRes sres;
sewardj5e519302008-11-03 23:10:25 +00001241 Int fd, i, j, lineno = 0;
philippe2193a7c2012-12-08 17:54:16 +00001242 Bool got_a_location_line_read_by_tool;
sewardj92645592005-07-23 09:18:34 +00001243 Bool eof;
njn35db56c2009-07-24 07:38:29 +00001244 SizeT nBuf = 200;
florian19f91bb2012-11-10 22:29:54 +00001245 HChar* buf = VG_(malloc)("errormgr.losf.1", nBuf);
1246 HChar* tool_names;
1247 HChar* supp_name;
florian2b8059a2012-10-14 16:45:23 +00001248 const HChar* err_str = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001249 SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
njnc40c3a82002-10-02 11:02:27 +00001250
njncc37d2e2009-06-24 03:49:19 +00001251 // Check it's not a directory.
1252 if (VG_(is_dir)( filename )) {
1253 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001254 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001255 VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
njncc37d2e2009-06-24 03:49:19 +00001256 VG_(exit)(1);
1257 }
1258
1259 // Open the suppression file.
sewardj92645592005-07-23 09:18:34 +00001260 sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001261 if (sr_isError(sres)) {
sewardjf349d552005-11-14 17:01:01 +00001262 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001263 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001264 VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
sewardjde4a1d02002-03-22 01:27:54 +00001265 VG_(exit)(1);
1266 }
njncda2f0f2009-05-18 02:12:08 +00001267 fd = sr_Res(sres);
sewardjde4a1d02002-03-22 01:27:54 +00001268
sewardj92645592005-07-23 09:18:34 +00001269# define BOMB(S) { err_str = S; goto syntax_error; }
sewardjb5f6f512005-03-10 23:59:00 +00001270
sewardjde4a1d02002-03-22 01:27:54 +00001271 while (True) {
nethercote7cc9c232004-01-21 15:08:04 +00001272 /* Assign and initialise the two suppression halves (core and tool) */
njn810086f2002-11-14 12:42:47 +00001273 Supp* supp;
sewardj9c606bd2008-09-18 18:12:50 +00001274 supp = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.1",
1275 sizeof(Supp));
sewardjde4a1d02002-03-22 01:27:54 +00001276 supp->count = 0;
sewardjb5f6f512005-03-10 23:59:00 +00001277
1278 // Initialise temporary reading-in buffer.
1279 for (i = 0; i < VG_MAX_SUPP_CALLERS; i++) {
1280 tmp_callers[i].ty = NoName;
philippe2c5c05e2012-07-26 21:37:36 +00001281 tmp_callers[i].name_is_simple_str = False;
sewardjb5f6f512005-03-10 23:59:00 +00001282 tmp_callers[i].name = NULL;
1283 }
1284
njn810086f2002-11-14 12:42:47 +00001285 supp->string = supp->extra = NULL;
sewardjde4a1d02002-03-22 01:27:54 +00001286
philippe2193a7c2012-12-08 17:54:16 +00001287 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
philippe7d69fd92012-02-26 21:26:00 +00001288 if (eof) {
1289 VG_(arena_free)(VG_AR_CORE, supp);
1290 break;
1291 }
sewardjde4a1d02002-03-22 01:27:54 +00001292
sewardjb5f6f512005-03-10 23:59:00 +00001293 if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
sewardjde4a1d02002-03-22 01:27:54 +00001294
philippe2193a7c2012-12-08 17:54:16 +00001295 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001296
1297 if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
1298
sewardj9c606bd2008-09-18 18:12:50 +00001299 supp->sname = VG_(arena_strdup)(VG_AR_CORE, "errormgr.losf.2", buf);
philippe362441d2013-07-22 22:00:13 +00001300 supp->clo_suppressions_i = clo_suppressions_i;
1301 supp->sname_lineno = lineno;
sewardjde4a1d02002-03-22 01:27:54 +00001302
philippe2193a7c2012-12-08 17:54:16 +00001303 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
njn25e49d8e72002-09-23 09:36:25 +00001304
philippe2193a7c2012-12-08 17:54:16 +00001305 if (eof) BOMB("unexpected end-of-file (expecting tool:suppr)");
sewardjde4a1d02002-03-22 01:27:54 +00001306
njn94065fd2004-11-22 19:26:27 +00001307 /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
njnc40c3a82002-10-02 11:02:27 +00001308 i = 0;
1309 while (True) {
1310 if (buf[i] == ':') break;
sewardjb5f6f512005-03-10 23:59:00 +00001311 if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
njnc40c3a82002-10-02 11:02:27 +00001312 i++;
njn25e49d8e72002-09-23 09:36:25 +00001313 }
njnc40c3a82002-10-02 11:02:27 +00001314 buf[i] = '\0'; /* Replace ':', splitting into two strings */
1315
nethercote7cc9c232004-01-21 15:08:04 +00001316 tool_names = & buf[0];
njn11cc9252002-10-07 14:42:59 +00001317 supp_name = & buf[i+1];
njnc40c3a82002-10-02 11:02:27 +00001318
nethercote7cc9c232004-01-21 15:08:04 +00001319 if (VG_(needs).core_errors && tool_name_present("core", tool_names))
njnc40c3a82002-10-02 11:02:27 +00001320 {
sewardjb5f6f512005-03-10 23:59:00 +00001321 // A core suppression
njna86f29e2006-12-14 02:55:58 +00001322 //(example code, see comment on CoreSuppKind above)
1323 //if (VG_STREQ(supp_name, "Thread"))
1324 // supp->skind = ThreadSupp;
1325 //else
sewardjb5f6f512005-03-10 23:59:00 +00001326 BOMB("unknown core suppression type");
njnc40c3a82002-10-02 11:02:27 +00001327 }
njn95ec8702004-11-22 16:46:13 +00001328 else if (VG_(needs).tool_errors &&
nethercote7cc9c232004-01-21 15:08:04 +00001329 tool_name_present(VG_(details).name, tool_names))
njnc40c3a82002-10-02 11:02:27 +00001330 {
sewardjb5f6f512005-03-10 23:59:00 +00001331 // A tool suppression
njn51d827b2005-05-09 01:02:08 +00001332 if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
njn810086f2002-11-14 12:42:47 +00001333 /* Do nothing, function fills in supp->skind */
sewardjb5f6f512005-03-10 23:59:00 +00001334 } else {
1335 BOMB("unknown tool suppression type");
1336 }
njnc40c3a82002-10-02 11:02:27 +00001337 }
njn25e49d8e72002-09-23 09:36:25 +00001338 else {
sewardjb5f6f512005-03-10 23:59:00 +00001339 // Ignore rest of suppression
njn25e49d8e72002-09-23 09:36:25 +00001340 while (True) {
philippe2193a7c2012-12-08 17:54:16 +00001341 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
1342 if (eof) BOMB("unexpected end-of-file (when skipping suppression)");
njn43c799e2003-04-08 00:08:52 +00001343 if (VG_STREQ(buf, "}"))
njn25e49d8e72002-09-23 09:36:25 +00001344 break;
1345 }
philippe7d69fd92012-02-26 21:26:00 +00001346 VG_(arena_free)(VG_AR_CORE, supp->sname);
1347 VG_(arena_free)(VG_AR_CORE, supp);
njn25e49d8e72002-09-23 09:36:25 +00001348 continue;
sewardjde4a1d02002-03-22 01:27:54 +00001349 }
1350
philippe2193a7c2012-12-08 17:54:16 +00001351 buf[0] = 0;
1352 // tool_read_extra_suppression_info might read lines
1353 // from fd till a location line.
njn95ec8702004-11-22 16:46:13 +00001354 if (VG_(needs).tool_errors &&
sewardjd7a02db2008-12-12 08:07:49 +00001355 !VG_TDICT_CALL(tool_read_extra_suppression_info,
philippe362441d2013-07-22 22:00:13 +00001356 fd, &buf, &nBuf, &lineno, supp))
sewardjb5f6f512005-03-10 23:59:00 +00001357 {
1358 BOMB("bad or missing extra suppression info");
sewardjde4a1d02002-03-22 01:27:54 +00001359 }
1360
philippe2193a7c2012-12-08 17:54:16 +00001361 got_a_location_line_read_by_tool = buf[0] != 0 && is_location_line(buf);
1362
sewardj5e519302008-11-03 23:10:25 +00001363 /* the main frame-descriptor reading loop */
sewardjb5f6f512005-03-10 23:59:00 +00001364 i = 0;
1365 while (True) {
philippe2193a7c2012-12-08 17:54:16 +00001366 if (got_a_location_line_read_by_tool) {
1367 got_a_location_line_read_by_tool = False;
1368 eof = False;
1369 } else {
1370 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
1371 }
sewardjb5f6f512005-03-10 23:59:00 +00001372 if (eof)
philippe2193a7c2012-12-08 17:54:16 +00001373 BOMB("unexpected end-of-file (when reading stack trace)");
sewardjb5f6f512005-03-10 23:59:00 +00001374 if (VG_STREQ(buf, "}")) {
1375 if (i > 0) {
1376 break;
1377 } else {
1378 BOMB("missing stack trace");
1379 }
1380 }
1381 if (i == VG_MAX_SUPP_CALLERS)
1382 BOMB("too many callers in stack trace");
1383 if (i > 0 && i >= VG_(clo_backtrace_size))
1384 break;
philippe7d69fd92012-02-26 21:26:00 +00001385 if (!setLocationTy(&(tmp_callers[i]), buf))
sewardj5e519302008-11-03 23:10:25 +00001386 BOMB("location should be \"...\", or should start "
1387 "with \"fun:\" or \"obj:\"");
sewardjb5f6f512005-03-10 23:59:00 +00001388 i++;
1389 }
1390
1391 // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
1392 // lines and grab the '}'.
sewardj57a8f5f2003-07-06 01:40:11 +00001393 if (!VG_STREQ(buf, "}")) {
sewardjb5f6f512005-03-10 23:59:00 +00001394 do {
philippe2193a7c2012-12-08 17:54:16 +00001395 eof = get_nbnc_line ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001396 } while (!eof && !VG_STREQ(buf, "}"));
1397 }
1398
sewardj5e519302008-11-03 23:10:25 +00001399 // Reject entries which are entirely composed of frame
1400 // level wildcards.
1401 vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
1402 for (j = 0; j < i; j++) {
1403 if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
1404 break;
1405 vg_assert(tmp_callers[j].ty == DotDotDot);
1406 }
1407 vg_assert(j >= 0 && j <= i);
1408 if (j == i) {
1409 // we didn't find any non-"..." entries
1410 BOMB("suppression must contain at least one location "
1411 "line which is not \"...\"");
1412 }
1413
sewardjb5f6f512005-03-10 23:59:00 +00001414 // Copy tmp_callers[] into supp->callers[]
1415 supp->n_callers = i;
sewardj9c606bd2008-09-18 18:12:50 +00001416 supp->callers = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.4",
1417 i*sizeof(SuppLoc));
sewardjb5f6f512005-03-10 23:59:00 +00001418 for (i = 0; i < supp->n_callers; i++) {
1419 supp->callers[i] = tmp_callers[i];
sewardj57a8f5f2003-07-06 01:40:11 +00001420 }
1421
njn695c16e2005-03-27 03:40:28 +00001422 supp->next = suppressions;
1423 suppressions = supp;
sewardjde4a1d02002-03-22 01:27:54 +00001424 }
njn35db56c2009-07-24 07:38:29 +00001425 VG_(free)(buf);
sewardjde4a1d02002-03-22 01:27:54 +00001426 VG_(close)(fd);
1427 return;
1428
1429 syntax_error:
sewardjf349d552005-11-14 17:01:01 +00001430 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001431 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001432 VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
njn6f74a7e2009-03-12 00:06:45 +00001433 filename, lineno );
sewardj738856f2009-07-15 14:48:32 +00001434 VG_(umsg)(" %s\n", err_str );
sewardjb5f6f512005-03-10 23:59:00 +00001435
sewardjde4a1d02002-03-22 01:27:54 +00001436 VG_(close)(fd);
sewardj738856f2009-07-15 14:48:32 +00001437 VG_(umsg)("exiting now.\n");
nethercote8ed8a892004-11-08 13:24:25 +00001438 VG_(exit)(1);
sewardjde4a1d02002-03-22 01:27:54 +00001439
sewardjb5f6f512005-03-10 23:59:00 +00001440# undef BOMB
sewardjde4a1d02002-03-22 01:27:54 +00001441}
1442
1443
1444void VG_(load_suppressions) ( void )
1445{
1446 Int i;
njn695c16e2005-03-27 03:40:28 +00001447 suppressions = NULL;
sewardjde4a1d02002-03-22 01:27:54 +00001448 for (i = 0; i < VG_(clo_n_suppressions); i++) {
1449 if (VG_(clo_verbosity) > 1) {
sewardj738856f2009-07-15 14:48:32 +00001450 VG_(dmsg)("Reading suppressions file: %s\n",
1451 VG_(clo_suppressions)[i] );
sewardjde4a1d02002-03-22 01:27:54 +00001452 }
philippe362441d2013-07-22 22:00:13 +00001453 load_one_suppressions_file( i );
sewardjde4a1d02002-03-22 01:27:54 +00001454 }
1455}
1456
sewardjd7a02db2008-12-12 08:07:49 +00001457
1458/*------------------------------------------------------------*/
1459/*--- Matching errors to suppressions ---*/
1460/*------------------------------------------------------------*/
1461
1462/* Parameterising functions for the use of VG_(generic_match) in
1463 suppression-vs-error matching. The suppression frames (SuppLoc)
1464 play the role of 'pattern'-element, and the error frames (IPs,
1465 hence simply Addrs) play the role of 'input'. In short then, we're
1466 matching a sequence of Addrs against a pattern composed of a
1467 sequence of SuppLocs.
1468*/
florian3e798632012-11-24 19:41:54 +00001469static Bool supploc_IsStar ( const void* supplocV )
sewardjd7a02db2008-12-12 08:07:49 +00001470{
florian3e798632012-11-24 19:41:54 +00001471 const SuppLoc* supploc = supplocV;
sewardjd7a02db2008-12-12 08:07:49 +00001472 return supploc->ty == DotDotDot;
1473}
1474
florian3e798632012-11-24 19:41:54 +00001475static Bool supploc_IsQuery ( const void* supplocV )
sewardjd7a02db2008-12-12 08:07:49 +00001476{
1477 return False; /* there's no '?' equivalent in the supp syntax */
1478}
1479
philippe13a59522012-08-03 23:11:39 +00001480/* IPtoFunOrObjCompleter is a lazy completer of the IPs
1481 needed to match an error with the suppression patterns.
1482 The matching between an IP and a suppression pattern is done either
1483 with the IP function name or with the IP object name.
1484 First time the fun or obj name is needed for an IP member
1485 of a stack trace, it will be computed and stored in names.
philippea0a73932014-06-15 15:42:20 +00001486 Also, if the IP corresponds to one or more inlined function calls,
1487 the inlined function names are expanded.
philippe13a59522012-08-03 23:11:39 +00001488 The IPtoFunOrObjCompleter type is designed to minimise the nr of
1489 allocations and the nr of debuginfo search. */
1490typedef
1491 struct {
1492 StackTrace ips; // stack trace we are lazily completing.
1493 UWord n_ips; // nr of elements in ips.
1494
philippea0a73932014-06-15 15:42:20 +00001495 // VG_(generic_match) calls haveInputInpC to check
1496 // for the presence of an input element identified by ixInput
1497 // (i.e. a number that identifies the ixInput element of the
1498 // input sequence). It calls supp_pattEQinp to match this input
1499 // element with a pattern.
1500 // When inlining info is used to provide inlined function calls
1501 // in stacktraces, one IP in ips can be expanded in several
1502 // function names. So, each time input (or presence of input)
1503 // is requested by VG_(generic_match), we will expand
1504 // more IP of ips till we have expanded enough to reach the
1505 // input element requested (or we cannot expand anymore).
1506
1507 UWord n_ips_expanded;
1508 // n_ips_expanded maintains the nr of elements in ips that we have
1509 // already expanded.
1510 UWord n_expanded;
1511 // n_expanded maintains the nr of elements resulting from the expansion
1512 // of the n_ips_expanded IPs. Without inlined function calls,
1513 // n_expanded == n_ips_expanded. With inlining info,
1514 // n_expanded >= n_ips_expanded.
1515
1516 Int* n_offsets_per_ip;
1517 // n_offsets_per_ip[i] gives the nr of offsets in fun_offsets and obj_offsets
1518 // resulting of the expansion of ips[i].
1519 // The sum of all n_expanded_per_ip must be equal to n_expanded.
1520 // This array allows to retrieve the position in ips corresponding to an ixInput.
1521
1522 // size (in elements) of fun_offsets and obj_offsets.
1523 // (fun|obj)_offsets are reallocated if more space is needed
1524 // to expand an IP.
1525 UWord sz_offsets;
1526
philippe13a59522012-08-03 23:11:39 +00001527 Int* fun_offsets;
philippea0a73932014-06-15 15:42:20 +00001528 // fun_offsets[ixInput] is the offset in names where the
1529 // function name for the ixInput element of the input sequence
1530 // can be found. As one IP of ips can be expanded in several
1531 // function calls due to inlined function calls, we can have more
1532 // elements in fun_offsets than in ips.
1533 // An offset -1 means the function name has not yet been computed.
philippe13a59522012-08-03 23:11:39 +00001534 Int* obj_offsets;
philippea0a73932014-06-15 15:42:20 +00001535 // Similarly, obj_offsets[ixInput] gives the offset for the
1536 // object name for ips[ixInput]
1537 // (-1 meaning object name not yet been computed).
philippe13a59522012-08-03 23:11:39 +00001538
1539 // All function names and object names will be concatenated
1540 // in names. names is reallocated on demand.
florian19f91bb2012-11-10 22:29:54 +00001541 HChar *names;
philippe13a59522012-08-03 23:11:39 +00001542 Int names_szB; // size of names.
florian19f91bb2012-11-10 22:29:54 +00001543 Int names_free; // offset first free HChar in names.
philippe13a59522012-08-03 23:11:39 +00001544 }
1545 IPtoFunOrObjCompleter;
1546
philippe5ab7ce82014-06-24 20:48:25 +00001547static void pp_ip2fo (IPtoFunOrObjCompleter* ip2fo)
philippe13a59522012-08-03 23:11:39 +00001548{
philippe5ab7ce82014-06-24 20:48:25 +00001549 Int i, j;
1550 Int o;
1551
1552 VG_(printf)("n_ips %lu n_ips_expanded %lu resulting in n_expanded %lu\n",
1553 ip2fo->n_ips, ip2fo->n_ips_expanded, ip2fo->n_expanded);
1554 for (i = 0; i < ip2fo->n_ips_expanded; i++) {
1555 o = 0;
1556 for (j = 0; j < i; j++)
1557 o += ip2fo->n_offsets_per_ip[j];
1558 VG_(printf)("ips %d 0x08%lx offset [%d,%d] ",
1559 i, ip2fo->ips[i],
1560 o, o+ip2fo->n_offsets_per_ip[i]-1);
1561 for (j = 0; j < ip2fo->n_offsets_per_ip[i]; j++) {
1562 VG_(printf)("%sfun:%s obj:%s\n",
1563 j == 0 ? "" : " ",
1564 ip2fo->fun_offsets[o+j] == -1 ?
1565 "<not expanded>" : &ip2fo->names[ip2fo->fun_offsets[o+j]],
1566 ip2fo->obj_offsets[o+j] == -1 ?
1567 "<not expanded>" : &ip2fo->names[ip2fo->obj_offsets[o+j]]);
1568 }
1569 }
1570}
1571
1572/* free the memory in ip2fo.
1573 At debuglog 4, su (or NULL) will be used to show the matching (or non matching)
1574 with ip2fo. */
1575static void clearIPtoFunOrObjCompleter ( Supp *su, IPtoFunOrObjCompleter* ip2fo)
1576{
1577 if (DEBUG_ERRORMGR || VG_(debugLog_getLevel)() >= 4) {
1578 if (su)
1579 VG_(dmsg)("errormgr matching end suppression %s %s:%d matched:\n",
1580 su->sname,
1581 VG_(clo_suppressions)[su->clo_suppressions_i],
1582 su->sname_lineno);
1583 else
1584 VG_(dmsg)("errormgr matching end no suppression matched:\n");
1585 VG_(pp_StackTrace) (ip2fo->ips, ip2fo->n_ips);
1586 pp_ip2fo(ip2fo);
1587 }
philippea0a73932014-06-15 15:42:20 +00001588 if (ip2fo->n_offsets_per_ip) VG_(free)(ip2fo->n_offsets_per_ip);
1589 if (ip2fo->fun_offsets) VG_(free)(ip2fo->fun_offsets);
1590 if (ip2fo->obj_offsets) VG_(free)(ip2fo->obj_offsets);
1591 if (ip2fo->names) VG_(free)(ip2fo->names);
philippe13a59522012-08-03 23:11:39 +00001592}
1593
philippea0a73932014-06-15 15:42:20 +00001594/* Grow ip2fo->names to ensure we have ERRTXT_LEN characters available
1595 in ip2fo->names and returns a pointer to the first free char. */
1596static HChar* grow_names(IPtoFunOrObjCompleter* ip2fo)
philippe13a59522012-08-03 23:11:39 +00001597{
philippea0a73932014-06-15 15:42:20 +00001598 if (ip2fo->names_szB
1599 < ip2fo->names_free + ERRTXT_LEN) {
1600 ip2fo->names
1601 = VG_(realloc)("foc_names",
1602 ip2fo->names,
1603 ip2fo->names_szB + ERRTXT_LEN);
1604 ip2fo->names_szB += ERRTXT_LEN;
1605 }
1606 return ip2fo->names + ip2fo->names_free;
1607}
1608
1609/* foComplete returns the function name or object name for ixInput.
1610 If needFun, returns the function name for this input
1611 else returns the object name for this input.
1612 The function name or object name will be computed and added in
1613 names if not yet done. */
1614static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo,
1615 Int ixInput, Bool needFun)
1616{
1617 vg_assert (ixInput < ip2fo->n_expanded);
1618 vg_assert (VG_(clo_read_inline_info) || ixInput < ip2fo->n_ips);
philippe13a59522012-08-03 23:11:39 +00001619
1620 // ptr to the offset array for function offsets (if needFun)
1621 // or object offsets (if !needFun).
1622 Int** offsets;
1623 if (needFun)
1624 offsets = &ip2fo->fun_offsets;
1625 else
1626 offsets = &ip2fo->obj_offsets;
1627
philippe13a59522012-08-03 23:11:39 +00001628 // Complete Fun name or Obj name for IP if not yet done.
philippea0a73932014-06-15 15:42:20 +00001629 if ((*offsets)[ixInput] == -1) {
1630 HChar* caller_name = grow_names(ip2fo);
1631 (*offsets)[ixInput] = ip2fo->names_free;
philippe5ab7ce82014-06-24 20:48:25 +00001632 if (DEBUG_ERRORMGR) VG_(printf)("marking %s ixInput %d offset %d\n",
1633 needFun ? "fun" : "obj",
1634 ixInput, ip2fo->names_free);
philippe13a59522012-08-03 23:11:39 +00001635 if (needFun) {
philippea0a73932014-06-15 15:42:20 +00001636 // With inline info, fn names must have been completed already.
1637 vg_assert (!VG_(clo_read_inline_info));
philippe13a59522012-08-03 23:11:39 +00001638 /* Get the function name into 'caller_name', or "???"
1639 if unknown. */
1640 // Nb: C++-mangled names are used in suppressions. Do, though,
1641 // Z-demangle them, since otherwise it's possible to wind
1642 // up comparing "malloc" in the suppression against
1643 // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
1644 // two of them need to be made to match.
philippea0a73932014-06-15 15:42:20 +00001645 if (!VG_(get_fnname_no_cxx_demangle)(ip2fo->ips[ixInput],
1646 caller_name, ERRTXT_LEN,
1647 NULL))
philippe13a59522012-08-03 23:11:39 +00001648 VG_(strcpy)(caller_name, "???");
1649 } else {
1650 /* Get the object name into 'caller_name', or "???"
1651 if unknown. */
philippea0a73932014-06-15 15:42:20 +00001652 UWord i;
1653 UWord last_expand_pos_ips = 0;
1654 UWord pos_ips;
1655
1656 /* First get the pos in ips corresponding to ixInput */
1657 for (pos_ips = 0; pos_ips < ip2fo->n_expanded; pos_ips++) {
1658 last_expand_pos_ips += ip2fo->n_offsets_per_ip[pos_ips];
philippe5ab7ce82014-06-24 20:48:25 +00001659 if (ixInput < last_expand_pos_ips)
philippea0a73932014-06-15 15:42:20 +00001660 break;
1661 }
1662 /* pos_ips is the position in ips corresponding to ixInput.
1663 last_expand_pos_ips is the last offset in fun/obj where
1664 ips[pos_ips] has been expanded. */
1665
1666 if (!VG_(get_objname)(ip2fo->ips[pos_ips], caller_name, ERRTXT_LEN))
philippe13a59522012-08-03 23:11:39 +00001667 VG_(strcpy)(caller_name, "???");
philippea0a73932014-06-15 15:42:20 +00001668
1669 // Have all inlined calls pointing at this object name
philippe5ab7ce82014-06-24 20:48:25 +00001670 for (i = last_expand_pos_ips - ip2fo->n_offsets_per_ip[pos_ips] + 1;
1671 i < last_expand_pos_ips;
1672 i++) {
philippea0a73932014-06-15 15:42:20 +00001673 ip2fo->obj_offsets[i] = ip2fo->names_free;
philippe5ab7ce82014-06-24 20:48:25 +00001674 if (DEBUG_ERRORMGR)
1675 VG_(printf) (" set obj_offset %lu to %d\n", i, ip2fo->names_free);
1676 }
philippe13a59522012-08-03 23:11:39 +00001677 }
1678 ip2fo->names_free += VG_(strlen)(caller_name) + 1;
philippe5ab7ce82014-06-24 20:48:25 +00001679 if (DEBUG_ERRORMGR) pp_ip2fo(ip2fo);
philippe13a59522012-08-03 23:11:39 +00001680 }
1681
philippea0a73932014-06-15 15:42:20 +00001682 return ip2fo->names + (*offsets)[ixInput];
1683}
1684
1685// Grow fun and obj _offsets arrays to have at least n_req elements.
1686// Ensure n_offsets_per_ip is allocated.
1687static void grow_offsets(IPtoFunOrObjCompleter* ip2fo, Int n_req)
1688{
1689 Int i;
1690
1691 // n_offsets_per_ip must always have the size of the ips array
1692 if (ip2fo->n_offsets_per_ip == NULL) {
1693 ip2fo->n_offsets_per_ip = VG_(malloc)("grow_offsets",
1694 ip2fo->n_ips * sizeof(Int));
1695 for (i = 0; i < ip2fo->n_ips; i++)
1696 ip2fo->n_offsets_per_ip[i] = 0;
1697 }
1698
1699 if (ip2fo->sz_offsets >= n_req)
1700 return;
1701
1702 // Avoid too much re-allocation by allocating at least ip2fo->n_ips
1703 // elements and at least a few more elements than the current size.
1704 if (n_req < ip2fo->n_ips)
1705 n_req = ip2fo->n_ips;
1706 if (n_req < ip2fo->sz_offsets + 5)
1707 n_req = ip2fo->sz_offsets + 5;
1708
1709 ip2fo->fun_offsets = VG_(realloc)("grow_offsets", ip2fo->fun_offsets,
1710 n_req * sizeof(Int));
1711 for (i = ip2fo->sz_offsets; i < n_req; i++)
1712 ip2fo->fun_offsets[i] = -1;
1713
1714 ip2fo->obj_offsets = VG_(realloc)("grow_offsets", ip2fo->obj_offsets,
1715 n_req * sizeof(Int));
1716 for (i = ip2fo->sz_offsets; i < n_req; i++)
1717 ip2fo->obj_offsets[i] = -1;
1718
1719 ip2fo->sz_offsets = n_req;
1720}
1721
1722// Expands more IPs from ip2fo->ips.
1723static void expandInput (IPtoFunOrObjCompleter* ip2fo, UWord ixInput )
1724{
1725 while (ip2fo->n_ips_expanded < ip2fo->n_ips
1726 && ip2fo->n_expanded <= ixInput) {
1727 if (VG_(clo_read_inline_info)) {
1728 // Expand one more IP in one or more calls.
1729 const Addr IP = ip2fo->ips[ip2fo->n_ips_expanded];
1730 InlIPCursor *iipc;
1731
1732 iipc = VG_(new_IIPC)(IP);
1733 // The only thing we really need is the nr of inlined fn calls
1734 // corresponding to the IP we will expand.
1735 // However, computing this is mostly the same as finding
1736 // the function name. So, let's directly complete the function name.
1737 do {
1738 HChar* caller_name = grow_names(ip2fo);
1739 grow_offsets(ip2fo, ip2fo->n_expanded+1);
1740 ip2fo->fun_offsets[ip2fo->n_expanded] = ip2fo->names_free;
1741 if (!VG_(get_fnname_no_cxx_demangle)(IP,
1742 caller_name, ERRTXT_LEN,
1743 iipc))
1744 VG_(strcpy)(caller_name, "???");
1745 ip2fo->names_free += VG_(strlen)(caller_name) + 1;
1746 ip2fo->n_expanded++;
1747 ip2fo->n_offsets_per_ip[ip2fo->n_ips_expanded]++;
1748 } while (VG_(next_IIPC)(iipc));
1749 ip2fo->n_ips_expanded++;
1750 VG_(delete_IIPC) (iipc);
1751 } else {
1752 // Without inlined fn call info, expansion simply
1753 // consists in allocating enough elements in (fun|obj)_offsets.
1754 // The function or object names themselves will be completed
1755 // when requested.
1756 Int i;
1757 grow_offsets(ip2fo, ip2fo->n_ips);
1758 ip2fo->n_ips_expanded = ip2fo->n_ips;
1759 ip2fo->n_expanded = ip2fo->n_ips;
1760 for (i = 0; i < ip2fo->n_ips; i++)
1761 ip2fo->n_offsets_per_ip[i] = 1;
1762 }
1763 }
1764}
1765
1766static Bool haveInputInpC (void* inputCompleter, UWord ixInput )
1767{
1768 IPtoFunOrObjCompleter* ip2fo = inputCompleter;
1769 expandInput(ip2fo, ixInput);
1770 return ixInput < ip2fo->n_expanded;
philippe13a59522012-08-03 23:11:39 +00001771}
1772
florian3e798632012-11-24 19:41:54 +00001773static Bool supp_pattEQinp ( const void* supplocV, const void* addrV,
philippea0a73932014-06-15 15:42:20 +00001774 void* inputCompleter, UWord ixInput )
sewardjd7a02db2008-12-12 08:07:49 +00001775{
florian3e798632012-11-24 19:41:54 +00001776 const SuppLoc* supploc = supplocV; /* PATTERN */
florian3e798632012-11-24 19:41:54 +00001777 IPtoFunOrObjCompleter* ip2fo = inputCompleter;
florian19f91bb2012-11-10 22:29:54 +00001778 HChar* funobj_name; // Fun or Obj name.
philippe5ab7ce82014-06-24 20:48:25 +00001779 Bool ret;
sewardjd7a02db2008-12-12 08:07:49 +00001780
philippea0a73932014-06-15 15:42:20 +00001781 expandInput(ip2fo, ixInput);
1782 vg_assert(ixInput < ip2fo->n_expanded);
1783
sewardjd7a02db2008-12-12 08:07:49 +00001784 /* So, does this IP address match this suppression-line? */
1785 switch (supploc->ty) {
1786 case DotDotDot:
1787 /* supp_pattEQinp is a callback from VG_(generic_match). As
1788 per the spec thereof (see include/pub_tool_seqmatch.h), we
1789 should never get called with a pattern value for which the
1790 _IsStar or _IsQuery function would return True. Hence
1791 this can't happen. */
1792 vg_assert(0);
1793 case ObjName:
philippea0a73932014-06-15 15:42:20 +00001794 funobj_name = foComplete(ip2fo, ixInput, False /*needFun*/);
sewardjd7a02db2008-12-12 08:07:49 +00001795 break;
philippe13a59522012-08-03 23:11:39 +00001796 case FunName:
philippea0a73932014-06-15 15:42:20 +00001797 funobj_name = foComplete(ip2fo, ixInput, True /*needFun*/);
sewardjd7a02db2008-12-12 08:07:49 +00001798 break;
1799 default:
1800 vg_assert(0);
1801 }
1802
philippe13a59522012-08-03 23:11:39 +00001803 /* So now we have the function or object name in funobj_name, and
sewardjd7a02db2008-12-12 08:07:49 +00001804 the pattern (at the character level) to match against is in
1805 supploc->name. Hence (and leading to a re-entrant call of
philippe2c5c05e2012-07-26 21:37:36 +00001806 VG_(generic_match) if there is a wildcard character): */
1807 if (supploc->name_is_simple_str)
philippe5ab7ce82014-06-24 20:48:25 +00001808 ret = VG_(strcmp) (supploc->name, funobj_name) == 0;
philippe2c5c05e2012-07-26 21:37:36 +00001809 else
philippe5ab7ce82014-06-24 20:48:25 +00001810 ret = VG_(string_match)(supploc->name, funobj_name);
1811 if (DEBUG_ERRORMGR)
1812 VG_(printf) ("supp_pattEQinp %s patt %s ixUnput %lu value:%s match:%s\n",
1813 supploc->ty == FunName ? "fun" : "obj",
1814 supploc->name, ixInput, funobj_name,
1815 ret ? "yes" : "no");
1816 return ret;
sewardjd7a02db2008-12-12 08:07:49 +00001817}
1818
1819/////////////////////////////////////////////////////
1820
philippe13a59522012-08-03 23:11:39 +00001821static Bool supp_matches_callers(IPtoFunOrObjCompleter* ip2fo, Supp* su)
sewardjd7a02db2008-12-12 08:07:49 +00001822{
1823 /* Unwrap the args and set up the correct parameterisation of
1824 VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
1825 supp_pattEQinp. */
philippe13a59522012-08-03 23:11:39 +00001826 /* note, StackTrace ip2fo->ips === Addr* */
sewardjd7a02db2008-12-12 08:07:49 +00001827 SuppLoc* supps = su->callers;
1828 UWord n_supps = su->n_callers;
1829 UWord szbPatt = sizeof(SuppLoc);
sewardjd7a02db2008-12-12 08:07:49 +00001830 Bool matchAll = False; /* we just want to match a prefix */
philippe5ab7ce82014-06-24 20:48:25 +00001831 if (DEBUG_ERRORMGR)
1832 VG_(dmsg)(" errormgr Checking match with %s %s:%d\n",
1833 su->sname,
1834 VG_(clo_suppressions)[su->clo_suppressions_i],
1835 su->sname_lineno);
sewardjd7a02db2008-12-12 08:07:49 +00001836 return
1837 VG_(generic_match)(
1838 matchAll,
philippea0a73932014-06-15 15:42:20 +00001839 /*PATT*/supps, szbPatt, n_supps, 0/*initial ixPatt*/,
1840 /*INPUT*/
1841 NULL, 0, 0, /* input/szbInput/nInput 0, as using an inputCompleter */
1842 0/*initial ixInput*/,
philippe13a59522012-08-03 23:11:39 +00001843 supploc_IsStar, supploc_IsQuery, supp_pattEQinp,
philippea0a73932014-06-15 15:42:20 +00001844 ip2fo, haveInputInpC
sewardjd7a02db2008-12-12 08:07:49 +00001845 );
1846}
1847
1848/////////////////////////////////////////////////////
1849
sewardjb5f6f512005-03-10 23:59:00 +00001850static
njn810086f2002-11-14 12:42:47 +00001851Bool supp_matches_error(Supp* su, Error* err)
njn25e49d8e72002-09-23 09:36:25 +00001852{
njn810086f2002-11-14 12:42:47 +00001853 switch (su->skind) {
njna86f29e2006-12-14 02:55:58 +00001854 //(example code, see comment on CoreSuppKind above)
1855 //case ThreadSupp:
1856 // return (err->ekind == ThreadErr);
njn25e49d8e72002-09-23 09:36:25 +00001857 default:
njn95ec8702004-11-22 16:46:13 +00001858 if (VG_(needs).tool_errors) {
njn51d827b2005-05-09 01:02:08 +00001859 return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
njn25e49d8e72002-09-23 09:36:25 +00001860 } else {
1861 VG_(printf)(
njn95ec8702004-11-22 16:46:13 +00001862 "\nUnhandled suppression type: %u. VG_(needs).tool_errors\n"
njn25e49d8e72002-09-23 09:36:25 +00001863 "probably needs to be set.\n",
njn810086f2002-11-14 12:42:47 +00001864 err->ekind);
njn67993252004-11-22 18:02:32 +00001865 VG_(tool_panic)("unhandled suppression type");
njn25e49d8e72002-09-23 09:36:25 +00001866 }
1867 }
1868}
1869
sewardjd7a02db2008-12-12 08:07:49 +00001870/////////////////////////////////////////////////////
sewardj5e519302008-11-03 23:10:25 +00001871
njn810086f2002-11-14 12:42:47 +00001872/* Does an error context match a suppression? ie is this a suppressible
1873 error? If so, return a pointer to the Supp record, otherwise NULL.
njn25e49d8e72002-09-23 09:36:25 +00001874 Tries to minimise the number of symbol searches since they are expensive.
sewardjde4a1d02002-03-22 01:27:54 +00001875*/
njn810086f2002-11-14 12:42:47 +00001876static Supp* is_suppressible_error ( Error* err )
sewardjde4a1d02002-03-22 01:27:54 +00001877{
njn810086f2002-11-14 12:42:47 +00001878 Supp* su;
sewardj8a7d4e42006-10-17 01:41:17 +00001879 Supp* su_prev;
1880
philippe13a59522012-08-03 23:11:39 +00001881 IPtoFunOrObjCompleter ip2fo;
1882 /* Conceptually, ip2fo contains an array of function names and an array of
1883 object names, corresponding to the array of IP of err->where.
1884 These names are just computed 'on demand' (so once maximum),
philippe4e32d672013-10-17 22:10:41 +00001885 then stored (efficiently, avoiding too many allocs) in ip2fo to be
1886 re-usable for the matching of the same IP with the next suppression
1887 pattern.
philippe13a59522012-08-03 23:11:39 +00001888
1889 VG_(generic_match) gets this 'IP to Fun or Obj name completer' as one
1890 of its arguments. It will then pass it to the function
1891 supp_pattEQinp which will then lazily complete the IP function name or
1892 object name inside ip2fo. Next time the fun or obj name for the same
1893 IP is needed (i.e. for the matching with the next suppr pattern), then
1894 the fun or obj name will not be searched again in the debug info. */
1895
sewardj8a7d4e42006-10-17 01:41:17 +00001896 /* stats gathering */
1897 em_supplist_searches++;
sewardjde4a1d02002-03-22 01:27:54 +00001898
philippe13a59522012-08-03 23:11:39 +00001899 /* Prepare the lazy input completer. */
1900 ip2fo.ips = VG_(get_ExeContext_StackTrace)(err->where);
1901 ip2fo.n_ips = VG_(get_ExeContext_n_ips)(err->where);
philippea0a73932014-06-15 15:42:20 +00001902 ip2fo.n_ips_expanded = 0;
1903 ip2fo.n_expanded = 0;
1904 ip2fo.sz_offsets = 0;
1905 ip2fo.n_offsets_per_ip = NULL;
philippe13a59522012-08-03 23:11:39 +00001906 ip2fo.fun_offsets = NULL;
1907 ip2fo.obj_offsets = NULL;
1908 ip2fo.names = NULL;
1909 ip2fo.names_szB = 0;
1910 ip2fo.names_free = 0;
1911
sewardjde4a1d02002-03-22 01:27:54 +00001912 /* See if the error context matches any suppression. */
philippe5ab7ce82014-06-24 20:48:25 +00001913 if (DEBUG_ERRORMGR || VG_(debugLog_getLevel)() >= 4)
1914 VG_(dmsg)("errormgr matching begin\n");
sewardj8a7d4e42006-10-17 01:41:17 +00001915 su_prev = NULL;
njn695c16e2005-03-27 03:40:28 +00001916 for (su = suppressions; su != NULL; su = su->next) {
sewardj8a7d4e42006-10-17 01:41:17 +00001917 em_supplist_cmps++;
philippe13a59522012-08-03 23:11:39 +00001918 if (supp_matches_error(su, err)
1919 && supp_matches_callers(&ip2fo, su)) {
philippe4e32d672013-10-17 22:10:41 +00001920 /* got a match. */
1921 /* Inform the tool that err is suppressed by su. */
1922 (void)VG_TDICT_CALL(tool_update_extra_suppression_use, err, su);
1923 /* Move this entry to the head of the list
sewardj8a7d4e42006-10-17 01:41:17 +00001924 in the hope of making future searches cheaper. */
1925 if (su_prev) {
1926 vg_assert(su_prev->next == su);
1927 su_prev->next = su->next;
1928 su->next = suppressions;
1929 suppressions = su;
1930 }
philippe5ab7ce82014-06-24 20:48:25 +00001931 clearIPtoFunOrObjCompleter(su, &ip2fo);
njn25e49d8e72002-09-23 09:36:25 +00001932 return su;
sewardjde4a1d02002-03-22 01:27:54 +00001933 }
sewardj8a7d4e42006-10-17 01:41:17 +00001934 su_prev = su;
sewardjde4a1d02002-03-22 01:27:54 +00001935 }
philippe5ab7ce82014-06-24 20:48:25 +00001936 clearIPtoFunOrObjCompleter(NULL, &ip2fo);
njn25e49d8e72002-09-23 09:36:25 +00001937 return NULL; /* no matches */
sewardjde4a1d02002-03-22 01:27:54 +00001938}
1939
sewardj8a7d4e42006-10-17 01:41:17 +00001940/* Show accumulated error-list and suppression-list search stats.
1941*/
1942void VG_(print_errormgr_stats) ( void )
1943{
sewardj738856f2009-07-15 14:48:32 +00001944 VG_(dmsg)(
1945 " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
sewardj8a7d4e42006-10-17 01:41:17 +00001946 em_supplist_searches, em_supplist_cmps
1947 );
sewardj738856f2009-07-15 14:48:32 +00001948 VG_(dmsg)(
1949 " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
sewardj8a7d4e42006-10-17 01:41:17 +00001950 em_errlist_searches, em_errlist_cmps
1951 );
1952}
1953
sewardjde4a1d02002-03-22 01:27:54 +00001954/*--------------------------------------------------------------------*/
njneb8896b2005-06-04 20:03:55 +00001955/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00001956/*--------------------------------------------------------------------*/