blob: 22f9a6e0dffbb648f03c5aa87bac326a12f0d6d8 [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
sewardjec062e82011-10-23 07:32:08 +000010 Copyright (C) 2000-2011 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"
njnd2b17112005-04-19 04:10:25 +000037#include "pub_core_errormgr.h"
njnd01fef72005-03-25 23:35:48 +000038#include "pub_core_execontext.h"
sewardj3b290482011-05-06 21:02:55 +000039#include "pub_core_gdbserver.h"
njn97405b22005-06-02 03:39:33 +000040#include "pub_core_libcbase.h"
njn132bfcc2005-06-04 19:16:06 +000041#include "pub_core_libcassert.h"
njneb8896b2005-06-04 20:03:55 +000042#include "pub_core_libcfile.h"
njn36a20fa2005-06-03 03:08:39 +000043#include "pub_core_libcprint.h"
njn24a6efb2005-06-20 03:36:51 +000044#include "pub_core_libcproc.h" // For VG_(getpid)()
sewardjd7a02db2008-12-12 08:07:49 +000045#include "pub_core_seqmatch.h"
njnaf1d7df2005-06-11 01:31:52 +000046#include "pub_core_mallocfree.h"
njn20242342005-05-16 23:31:24 +000047#include "pub_core_options.h"
njnd0d7c1f2005-06-21 00:33:19 +000048#include "pub_core_stacktrace.h"
njn43b9a8a2005-05-10 04:37:01 +000049#include "pub_core_tooliface.h"
njn24a6efb2005-06-20 03:36:51 +000050#include "pub_core_translate.h" // for VG_(translate)()
sewardj588adef2009-08-15 22:41:51 +000051#include "pub_core_xarray.h" // VG_(xaprintf) et al
sewardjde4a1d02002-03-22 01:27:54 +000052
53/*------------------------------------------------------------*/
njn25e49d8e72002-09-23 09:36:25 +000054/*--- Globals ---*/
sewardjde4a1d02002-03-22 01:27:54 +000055/*------------------------------------------------------------*/
56
njn14319cc2005-03-13 06:26:22 +000057/* After this many different unsuppressed errors have been observed,
58 be more conservative about collecting new ones. */
sewardj1d1a2262005-10-20 01:57:29 +000059#define M_COLLECT_ERRORS_SLOWLY_AFTER 100
njn14319cc2005-03-13 06:26:22 +000060
61/* After this many different unsuppressed errors have been observed,
62 stop collecting errors at all, and tell the user their program is
63 evidently a steaming pile of camel dung. */
sewardj1d1a2262005-10-20 01:57:29 +000064#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 1000
njn14319cc2005-03-13 06:26:22 +000065
66/* After this many total errors have been observed, stop collecting
67 errors at all. Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
sewardj513646f2006-05-12 23:12:30 +000068#define M_COLLECT_NO_ERRORS_AFTER_FOUND 10000000
njn14319cc2005-03-13 06:26:22 +000069
sewardjde4a1d02002-03-22 01:27:54 +000070/* The list of error contexts found, both suppressed and unsuppressed.
71 Initially empty, and grows as errors are detected. */
njn695c16e2005-03-27 03:40:28 +000072static Error* errors = NULL;
sewardjde4a1d02002-03-22 01:27:54 +000073
74/* The list of suppression directives, as read from the specified
sewardj8a7d4e42006-10-17 01:41:17 +000075 suppressions file. Note that the list gets rearranged as a result
76 of the searches done by is_suppressible_error(). */
njn695c16e2005-03-27 03:40:28 +000077static Supp* suppressions = NULL;
sewardjde4a1d02002-03-22 01:27:54 +000078
79/* Running count of unsuppressed errors detected. */
nethercotef2b11482004-08-02 12:36:01 +000080static UInt n_errs_found = 0;
sewardjde4a1d02002-03-22 01:27:54 +000081
82/* Running count of suppressed errors detected. */
nethercotef2b11482004-08-02 12:36:01 +000083static UInt n_errs_suppressed = 0;
sewardjde4a1d02002-03-22 01:27:54 +000084
philippebaf69642012-02-15 22:29:30 +000085/* Running count of errors shown. */
86static UInt n_errs_shown = 0;
87
njn606a4ae2009-08-11 00:52:40 +000088/* Running count of unsuppressed error contexts. */
89static UInt n_err_contexts = 0;
90
91/* Running count of suppressed error contexts. */
92static UInt n_supp_contexts = 0;
93
94
sewardjde4a1d02002-03-22 01:27:54 +000095/* forwards ... */
njn810086f2002-11-14 12:42:47 +000096static Supp* is_suppressible_error ( Error* err );
sewardjde4a1d02002-03-22 01:27:54 +000097
sewardjb5f6f512005-03-10 23:59:00 +000098static ThreadId last_tid_printed = 1;
sewardjde4a1d02002-03-22 01:27:54 +000099
sewardj8a7d4e42006-10-17 01:41:17 +0000100/* Stats: number of searches of the error list initiated. */
101static UWord em_errlist_searches = 0;
102
103/* Stats: number of comparisons done during error list
104 searching. */
105static UWord em_errlist_cmps = 0;
106
107/* Stats: number of searches of the suppression list initiated. */
108static UWord em_supplist_searches = 0;
109
110/* Stats: number of comparisons done during suppression list
111 searching. */
112static UWord em_supplist_cmps = 0;
113
sewardjde4a1d02002-03-22 01:27:54 +0000114/*------------------------------------------------------------*/
nethercote4a184902004-08-02 12:21:09 +0000115/*--- Error type ---*/
116/*------------------------------------------------------------*/
117
nethercote4a184902004-08-02 12:21:09 +0000118/* Errors. Extensible (via the 'extra' field). Tools can use a normal
njn02bc4b82005-05-15 17:28:26 +0000119 enum (with element values in the normal range (0..)) for 'ekind'.
nethercote4a184902004-08-02 12:21:09 +0000120 Functions for getting/setting the tool-relevant fields are in
njnc7561b92005-06-19 01:24:32 +0000121 include/pub_tool_errormgr.h.
nethercote4a184902004-08-02 12:21:09 +0000122
123 When errors are found and recorded with VG_(maybe_record_error)(), all
124 the tool must do is pass in the four parameters; core will
125 allocate/initialise the error record.
126*/
127struct _Error {
128 struct _Error* next;
sewardjdbada272005-07-02 21:16:30 +0000129 // Unique tag. This gives the error a unique identity (handle) by
130 // which it can be referred to afterwords. Currently only used for
131 // XML printing.
132 UInt unique;
nethercote4a184902004-08-02 12:21:09 +0000133 // NULL if unsuppressed; or ptr to suppression record.
134 Supp* supp;
135 Int count;
nethercote4a184902004-08-02 12:21:09 +0000136
137 // The tool-specific part
sewardjb8b79ad2008-03-03 01:35:41 +0000138 ThreadId tid; // Initialised by core
nethercote4a184902004-08-02 12:21:09 +0000139 ExeContext* where; // Initialised by core
njnd2b17112005-04-19 04:10:25 +0000140 ErrorKind ekind; // Used by ALL. Must be in the range (0..)
nethercote4a184902004-08-02 12:21:09 +0000141 Addr addr; // Used frequently
142 Char* string; // Used frequently
143 void* extra; // For any tool-specific extras
144};
145
sewardjb8b79ad2008-03-03 01:35:41 +0000146
nethercote4a184902004-08-02 12:21:09 +0000147ExeContext* VG_(get_error_where) ( Error* err )
148{
149 return err->where;
150}
151
152ErrorKind VG_(get_error_kind) ( Error* err )
153{
154 return err->ekind;
155}
156
157Addr VG_(get_error_address) ( Error* err )
158{
159 return err->addr;
160}
161
162Char* VG_(get_error_string) ( Error* err )
163{
164 return err->string;
165}
166
167void* VG_(get_error_extra) ( Error* err )
168{
169 return err->extra;
170}
171
nethercotef2b11482004-08-02 12:36:01 +0000172UInt VG_(get_n_errs_found)( void )
173{
174 return n_errs_found;
175}
176
philippebaf69642012-02-15 22:29:30 +0000177UInt VG_(get_n_errs_shown)( void )
178{
179 return n_errs_shown;
180}
181
nethercote4a184902004-08-02 12:21:09 +0000182/*------------------------------------------------------------*/
183/*--- Suppression type ---*/
184/*------------------------------------------------------------*/
185
186/* Note: it is imperative this doesn't overlap with (0..) at all, as tools
187 * effectively extend it by defining their own enums in the (0..) range. */
188typedef
189 enum {
njna86f29e2006-12-14 02:55:58 +0000190 // Nb: thread errors are a relic of the time when Valgrind's core
191 // could detect them. This example is left commented-out as an
192 // example should new core errors ever be added.
193 ThreadSupp = -1, /* Matches ThreadErr */
nethercote4a184902004-08-02 12:21:09 +0000194 }
195 CoreSuppKind;
196
sewardjb5f6f512005-03-10 23:59:00 +0000197/* Max number of callers for context in a suppression. */
198#define VG_MAX_SUPP_CALLERS 24
199
nethercote4a184902004-08-02 12:21:09 +0000200/* For each caller specified for a suppression, record the nature of
201 the caller name. Not of interest to tools. */
202typedef
203 enum {
sewardjb5f6f512005-03-10 23:59:00 +0000204 NoName, /* Error case */
nethercote4a184902004-08-02 12:21:09 +0000205 ObjName, /* Name is of an shared object file. */
sewardj5e519302008-11-03 23:10:25 +0000206 FunName, /* Name is of a function. */
207 DotDotDot /* Frame-level wildcard */
nethercote4a184902004-08-02 12:21:09 +0000208 }
209 SuppLocTy;
210
sewardjb5f6f512005-03-10 23:59:00 +0000211typedef
212 struct {
213 SuppLocTy ty;
philippe2c5c05e2012-07-26 21:37:36 +0000214 Bool name_is_simple_str; /* True if name is a string without
215 '?' and '*' wildcard characters. */
sewardj5e519302008-11-03 23:10:25 +0000216 Char* name; /* NULL for NoName and DotDotDot */
sewardjb5f6f512005-03-10 23:59:00 +0000217 }
218 SuppLoc;
219
nethercote4a184902004-08-02 12:21:09 +0000220/* Suppressions. Tools can get/set tool-relevant parts with functions
njnc7561b92005-06-19 01:24:32 +0000221 declared in include/pub_tool_errormgr.h. Extensible via the 'extra' field.
nethercote4a184902004-08-02 12:21:09 +0000222 Tools can use a normal enum (with element values in the normal range
njn02bc4b82005-05-15 17:28:26 +0000223 (0..)) for 'skind'. */
nethercote4a184902004-08-02 12:21:09 +0000224struct _Supp {
225 struct _Supp* next;
226 Int count; // The number of times this error has been suppressed.
227 Char* sname; // The name by which the suppression is referred to.
sewardjb5f6f512005-03-10 23:59:00 +0000228
229 // Length of 'callers'
230 Int n_callers;
231 // Array of callers, for matching stack traces. First one (name of fn
232 // where err occurs) is mandatory; rest are optional.
233 SuppLoc* callers;
nethercote4a184902004-08-02 12:21:09 +0000234
235 /* The tool-specific part */
236 SuppKind skind; // What kind of suppression. Must use the range (0..).
237 Char* string; // String -- use is optional. NULL by default.
238 void* extra; // Anything else -- use is optional. NULL by default.
239};
240
241SuppKind VG_(get_supp_kind) ( Supp* su )
242{
243 return su->skind;
244}
245
246Char* VG_(get_supp_string) ( Supp* su )
247{
248 return su->string;
249}
250
251void* VG_(get_supp_extra) ( Supp* su )
252{
253 return su->extra;
254}
255
256
257void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
258{
259 su->skind = skind;
260}
261
262void VG_(set_supp_string) ( Supp* su, Char* string )
263{
264 su->string = string;
265}
266
267void VG_(set_supp_extra) ( Supp* su, void* extra )
268{
269 su->extra = extra;
270}
271
272
273/*------------------------------------------------------------*/
sewardjde4a1d02002-03-22 01:27:54 +0000274/*--- Helper fns ---*/
275/*------------------------------------------------------------*/
276
njn0087c502005-07-01 04:15:36 +0000277// Only show core errors if the tool wants to, we're not running with -q,
278// and were not outputting XML.
279Bool VG_(showing_core_errors)(void)
280{
281 return VG_(needs).core_errors && VG_(clo_verbosity) >= 1 && !VG_(clo_xml);
282}
283
sewardj738856f2009-07-15 14:48:32 +0000284/* Compare errors, to detect duplicates.
285*/
njn810086f2002-11-14 12:42:47 +0000286static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
sewardjde4a1d02002-03-22 01:27:54 +0000287{
njn810086f2002-11-14 12:42:47 +0000288 if (e1->ekind != e2->ekind)
sewardjde4a1d02002-03-22 01:27:54 +0000289 return False;
njn25e49d8e72002-09-23 09:36:25 +0000290 if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
sewardjde4a1d02002-03-22 01:27:54 +0000291 return False;
292
njn810086f2002-11-14 12:42:47 +0000293 switch (e1->ekind) {
njna86f29e2006-12-14 02:55:58 +0000294 //(example code, see comment on CoreSuppKind above)
295 //case ThreadErr:
296 // vg_assert(VG_(needs).core_errors);
297 // return <something>
sewardjde4a1d02002-03-22 01:27:54 +0000298 default:
njn51d827b2005-05-09 01:02:08 +0000299 if (VG_(needs).tool_errors) {
300 return VG_TDICT_CALL(tool_eq_Error, res, e1, e2);
301 } else {
njn95ec8702004-11-22 16:46:13 +0000302 VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_errors\n"
njn25e49d8e72002-09-23 09:36:25 +0000303 "probably needs to be set.\n",
njn810086f2002-11-14 12:42:47 +0000304 e1->ekind);
njn67993252004-11-22 18:02:32 +0000305 VG_(tool_panic)("unhandled error type");
njn25e49d8e72002-09-23 09:36:25 +0000306 }
sewardjde4a1d02002-03-22 01:27:54 +0000307 }
308}
309
sewardj738856f2009-07-15 14:48:32 +0000310
sewardj588adef2009-08-15 22:41:51 +0000311/* Helper functions for suppression generation: print a single line of
312 a suppression pseudo-stack-trace, either in XML or text mode. It's
313 important that the behaviour of these two functions exactly
314 corresponds.
sewardj738856f2009-07-15 14:48:32 +0000315*/
316#define ERRTXT_LEN 4096
317
sewardj588adef2009-08-15 22:41:51 +0000318static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque)
sewardjde4a1d02002-03-22 01:27:54 +0000319{
sewardj738856f2009-07-15 14:48:32 +0000320 static UChar buf[ERRTXT_LEN];
sewardj738856f2009-07-15 14:48:32 +0000321 if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
bartb3af9cf2011-10-06 19:08:37 +0000322 VG_(printf_xml)(" <sframe> <fun>%pS</fun> </sframe>\n", buf);
sewardj588adef2009-08-15 22:41:51 +0000323 } else
324 if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
bartb3af9cf2011-10-06 19:08:37 +0000325 VG_(printf_xml)(" <sframe> <obj>%pS</obj> </sframe>\n", buf);
sewardj738856f2009-07-15 14:48:32 +0000326 } else {
bartb3af9cf2011-10-06 19:08:37 +0000327 VG_(printf_xml)(" <sframe> <obj>*</obj> </sframe>\n");
sewardjde4a1d02002-03-22 01:27:54 +0000328 }
329}
330
sewardj588adef2009-08-15 22:41:51 +0000331static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV)
332{
333 static UChar buf[ERRTXT_LEN];
334 XArray* /* of HChar */ text = (XArray*)textV;
335 if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN) ) {
336 VG_(xaprintf)(text, " fun:%s\n", buf);
337 } else
338 if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) {
339 VG_(xaprintf)(text, " obj:%s\n", buf);
340 } else {
341 VG_(xaprintf)(text, " obj:*\n");
342 }
343}
sewardj738856f2009-07-15 14:48:32 +0000344
345/* Generate a suppression for an error, either in text or XML mode.
346*/
347static void gen_suppression(Error* err)
348{
sewardj588adef2009-08-15 22:41:51 +0000349 Char xtra[256]; /* assumed big enough (is overrun-safe) */
350 Bool anyXtra;
351 Char* name;
352 ExeContext* ec;
353 XArray* /* HChar */ text;
sewardj738856f2009-07-15 14:48:32 +0000354
sewardj588adef2009-08-15 22:41:51 +0000355 const HChar* dummy_name = "insert_a_suppression_name_here";
sewardj738856f2009-07-15 14:48:32 +0000356
sewardj588adef2009-08-15 22:41:51 +0000357 vg_assert(err);
358
sewardj588adef2009-08-15 22:41:51 +0000359 ec = VG_(get_error_where)(err);
360 vg_assert(ec);
361
362 name = VG_TDICT_CALL(tool_get_error_name, err);
363 if (NULL == name) {
364 VG_(umsg)("(%s does not allow error to be suppressed)\n",
365 VG_(details).name);
366 return;
sewardj738856f2009-07-15 14:48:32 +0000367 }
368
tom7420e0a2011-07-06 14:08:24 +0000369 /* In XML mode, we also need to print the plain text version of the
370 suppresion in a CDATA section. What that really means is, we
371 need to generate the plaintext version both in XML and text
372 mode. So generate it into TEXT. */
373 text = VG_(newXA)( VG_(malloc), "errormgr.gen_suppression.1",
374 VG_(free), sizeof(HChar) );
375 vg_assert(text);
376
sewardj588adef2009-08-15 22:41:51 +0000377 /* Ok. Generate the plain text version into TEXT. */
378 VG_(xaprintf)(text, "{\n");
379 VG_(xaprintf)(text, " <%s>\n", dummy_name);
380 VG_(xaprintf)(text, " %s:%s\n", VG_(details).name, name);
381
382 VG_(memset)(xtra, 0, sizeof(xtra));
383 anyXtra = VG_TDICT_CALL(tool_get_extra_suppression_info,
384 err, xtra, sizeof(xtra));
385 vg_assert(xtra[sizeof(xtra)-1] == 0);
386
387 if (anyXtra)
388 VG_(xaprintf)(text, " %s\n", xtra);
389
sewardj738856f2009-07-15 14:48:32 +0000390 // Print stack trace elements
sewardj2f340eb2011-01-28 00:44:52 +0000391 UInt n_ips = VG_(get_ExeContext_n_ips)(ec);
392 tl_assert(n_ips > 0);
393 if (n_ips > VG_MAX_SUPP_CALLERS)
394 n_ips = VG_MAX_SUPP_CALLERS;
sewardj588adef2009-08-15 22:41:51 +0000395 VG_(apply_StackTrace)(printSuppForIp_nonXML,
396 text,
sewardj738856f2009-07-15 14:48:32 +0000397 VG_(get_ExeContext_StackTrace)(ec),
sewardj2f340eb2011-01-28 00:44:52 +0000398 n_ips);
sewardj738856f2009-07-15 14:48:32 +0000399
sewardj588adef2009-08-15 22:41:51 +0000400 VG_(xaprintf)(text, "}\n");
401 // zero terminate
402 VG_(xaprintf)(text, "%c", (HChar)0 );
403 // VG_(printf) of text
404
405 /* And now display it. */
406 if (! VG_(clo_xml) ) {
407
408 // the simple case
409 VG_(printf)("%s", (HChar*) VG_(indexXA)(text, 0) );
410
sewardj738856f2009-07-15 14:48:32 +0000411 } else {
sewardj588adef2009-08-15 22:41:51 +0000412
413 /* Now we have to print the XML directly. No need to go to the
414 effort of stuffing it in an XArray, since we won't need it
415 again. */
416 VG_(printf_xml)(" <suppression>\n");
417 VG_(printf_xml)(" <sname>%s</sname>\n", dummy_name);
bartb3af9cf2011-10-06 19:08:37 +0000418 VG_(printf_xml)(
419 " <skind>%pS:%pS</skind>\n", VG_(details).name, name);
sewardj588adef2009-08-15 22:41:51 +0000420 if (anyXtra)
bartb3af9cf2011-10-06 19:08:37 +0000421 VG_(printf_xml)(" <skaux>%pS</skaux>\n", xtra);
sewardj588adef2009-08-15 22:41:51 +0000422
423 // Print stack trace elements
424 VG_(apply_StackTrace)(printSuppForIp_XML,
425 NULL,
426 VG_(get_ExeContext_StackTrace)(ec),
427 VG_(get_ExeContext_n_ips)(ec));
428
429 // And now the cdata bit
430 // XXX FIXME! properly handle the case where the raw text
431 // itself contains "]]>", as specified in Protocol 4.
432 VG_(printf_xml)(" <rawtext>\n");
433 VG_(printf_xml)("<![CDATA[\n");
sewardjde78f9a2009-08-15 23:33:04 +0000434 VG_(printf_xml)("%s", (HChar*) VG_(indexXA)(text, 0) );
sewardj588adef2009-08-15 22:41:51 +0000435 VG_(printf_xml)("]]>\n");
436 VG_(printf_xml)(" </rawtext>\n");
437 VG_(printf_xml)(" </suppression>\n");
438
sewardj738856f2009-07-15 14:48:32 +0000439 }
sewardj588adef2009-08-15 22:41:51 +0000440
441 VG_(deleteXA)(text);
sewardj738856f2009-07-15 14:48:32 +0000442}
443
444
445/* Figure out if we want to perform a given action for this error,
446 possibly by asking the user.
447*/
njn43c799e2003-04-08 00:08:52 +0000448Bool VG_(is_action_requested) ( Char* action, Bool* clo )
sewardjde4a1d02002-03-22 01:27:54 +0000449{
450 Char ch, ch2;
451 Int res;
452
sewardj738856f2009-07-15 14:48:32 +0000453 /* First off, we shouldn't be asking the user anything if
454 we're in XML mode. */
455 if (VG_(clo_xml))
456 return False; /* That's a Nein, oder Nay as they say down here in B-W */
457
njn43c799e2003-04-08 00:08:52 +0000458 if (*clo == False)
sewardjde4a1d02002-03-22 01:27:54 +0000459 return False;
460
sewardj738856f2009-07-15 14:48:32 +0000461 VG_(umsg)("\n");
sewardjde4a1d02002-03-22 01:27:54 +0000462
463 again:
464 VG_(printf)(
465 "==%d== "
njn43c799e2003-04-08 00:08:52 +0000466 "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",
467 VG_(getpid)(), action
sewardjde4a1d02002-03-22 01:27:54 +0000468 );
469
sewardj6024b212003-07-13 10:54:33 +0000470 res = VG_(read)(VG_(clo_input_fd), &ch, 1);
sewardjde4a1d02002-03-22 01:27:54 +0000471 if (res != 1) goto ioerror;
472 /* res == 1 */
473 if (ch == '\n') return False;
474 if (ch != 'N' && ch != 'n' && ch != 'Y' && ch != 'y'
475 && ch != 'C' && ch != 'c') goto again;
476
sewardj6024b212003-07-13 10:54:33 +0000477 res = VG_(read)(VG_(clo_input_fd), &ch2, 1);
sewardjde4a1d02002-03-22 01:27:54 +0000478 if (res != 1) goto ioerror;
479 if (ch2 != '\n') goto again;
480
njn43c799e2003-04-08 00:08:52 +0000481 /* No, don't want to do action. */
sewardjde4a1d02002-03-22 01:27:54 +0000482 if (ch == 'n' || ch == 'N') return False;
njn43c799e2003-04-08 00:08:52 +0000483 /* Yes, want to do action. */
sewardjde4a1d02002-03-22 01:27:54 +0000484 if (ch == 'y' || ch == 'Y') return True;
njn43c799e2003-04-08 00:08:52 +0000485 /* No, don't want to do action, and don't ask again either. */
sewardjde4a1d02002-03-22 01:27:54 +0000486 vg_assert(ch == 'c' || ch == 'C');
487
488 ioerror:
njn43c799e2003-04-08 00:08:52 +0000489 *clo = False;
sewardjde4a1d02002-03-22 01:27:54 +0000490 return False;
491}
492
493
sewardj738856f2009-07-15 14:48:32 +0000494/* Do text-mode actions on error, that is, immediately after an error
495 is printed. These are:
496 * possibly, attach to a debugger
497 * possibly, generate a suppression.
498 Note this should not be called in XML mode!
499*/
500static
501void do_actions_on_error(Error* err, Bool allow_db_attach)
502{
503 Bool still_noisy = True;
504
505 /* Should be assured by caller */
506 vg_assert( ! VG_(clo_xml) );
507
sewardj3b290482011-05-06 21:02:55 +0000508 /* if user wants to debug from a certain error nr, then wait for gdb/vgdb */
509 if (VG_(clo_vgdb) != Vg_VgdbNo
510 && allow_db_attach
philippebaf69642012-02-15 22:29:30 +0000511 && VG_(dyn_vgdb_error) <= n_errs_shown) {
sewardj3b290482011-05-06 21:02:55 +0000512 VG_(umsg)("(action on error) vgdb me ... \n");
513 VG_(gdbserver)( err->tid );
514 VG_(umsg)("Continuing ...\n");
515 }
516
sewardj738856f2009-07-15 14:48:32 +0000517 /* Perhaps we want a debugger attach at this point? */
sewardj3b290482011-05-06 21:02:55 +0000518 /* GDBTD ??? maybe we should/could remove the below assuming the
519 gdbserver interface is better ??? */
sewardj738856f2009-07-15 14:48:32 +0000520 if (allow_db_attach &&
521 VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_attach) ))
522 {
523 if (0) VG_(printf)("starting debugger\n");
524 VG_(start_debugger)( err->tid );
525 }
526 /* Or maybe we want to generate the error's suppression? */
527 if (VG_(clo_gen_suppressions) == 2
528 || (VG_(clo_gen_suppressions) == 1
529 && VG_(is_action_requested)( "Print suppression", &still_noisy ))
530 ) {
531 gen_suppression(err);
532 }
533 if (VG_(clo_gen_suppressions) == 1 && !still_noisy)
534 VG_(clo_gen_suppressions) = 0;
535}
536
537
538/* Prints an error. Not entirely simple because of the differences
539 between XML and text mode output.
540
541 In XML mode:
542
543 * calls the tool's pre-show method, so the tool can create any
544 preamble ahead of the message, if it wants.
545
546 * prints the opening tag, and the <unique> and <tid> fields
547
548 * prints the tool-specific parts of the message
549
550 * if suppression generation is required, a suppression
551
552 * the closing tag
553
554 In text mode:
555
556 * calls the tool's pre-show method, so the tool can create any
557 preamble ahead of the message, if it wants.
558
559 * prints the tool-specific parts of the message
560
561 * calls do_actions_on_error. This optionally does a debugger
562 attach (and detach), and optionally prints a suppression; both
563 of these may require user input.
564*/
sewardj3b290482011-05-06 21:02:55 +0000565static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
sewardj738856f2009-07-15 14:48:32 +0000566{
567 /* If this fails, you probably specified your tool's method
568 dictionary incorrectly. */
569 vg_assert(VG_(needs).tool_errors);
570
sewardj3b290482011-05-06 21:02:55 +0000571 if (xml) {
sewardj738856f2009-07-15 14:48:32 +0000572
573 /* Note, allow_db_attach is ignored in here. */
574
575 /* Ensure that suppression generation is either completely
576 enabled or completely disabled; either way, we won't require
577 any user input. m_main.process_cmd_line_options should
578 ensure the asserted condition holds. */
579 vg_assert( VG_(clo_gen_suppressions) == 0 /* disabled */
580 || VG_(clo_gen_suppressions) == 2 /* for all errors */ );
581
582 /* Pre-show it to the tool */
583 VG_TDICT_CALL( tool_before_pp_Error, err );
584
585 /* standard preamble */
586 VG_(printf_xml)("<error>\n");
587 VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
588 VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
589
590 /* actually print it */
591 VG_TDICT_CALL( tool_pp_Error, err );
592
593 if (VG_(clo_gen_suppressions) > 0)
594 gen_suppression(err);
595
596 /* postamble */
597 VG_(printf_xml)("</error>\n");
njnb6267bd2009-08-12 00:14:16 +0000598 VG_(printf_xml)("\n");
sewardj738856f2009-07-15 14:48:32 +0000599
600 } else {
601
602 VG_TDICT_CALL( tool_before_pp_Error, err );
603
604 if (VG_(tdict).tool_show_ThreadIDs_for_errors
605 && err->tid > 0 && err->tid != last_tid_printed) {
606 VG_(umsg)("Thread %d:\n", err->tid );
607 last_tid_printed = err->tid;
608 }
609
610 VG_TDICT_CALL( tool_pp_Error, err );
njnb6267bd2009-08-12 00:14:16 +0000611 VG_(umsg)("\n");
sewardj738856f2009-07-15 14:48:32 +0000612
613 do_actions_on_error(err, allow_db_attach);
sewardj738856f2009-07-15 14:48:32 +0000614 }
615}
616
617
sewardjb5f6f512005-03-10 23:59:00 +0000618/* Construct an error */
sewardj738856f2009-07-15 14:48:32 +0000619static
njn72718642003-07-24 08:45:32 +0000620void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a,
621 Char* s, void* extra, ExeContext* where )
sewardjde4a1d02002-03-22 01:27:54 +0000622{
sewardjdbada272005-07-02 21:16:30 +0000623 /* DO NOT MAKE unique_counter NON-STATIC */
624 static UInt unique_counter = 0;
625
njnca82cc02004-11-22 17:18:48 +0000626 tl_assert(tid < VG_N_THREADS);
njn72718642003-07-24 08:45:32 +0000627
njn810086f2002-11-14 12:42:47 +0000628 /* Core-only parts */
sewardjdbada272005-07-02 21:16:30 +0000629 err->unique = unique_counter++;
njn25e49d8e72002-09-23 09:36:25 +0000630 err->next = NULL;
631 err->supp = NULL;
632 err->count = 1;
njn72718642003-07-24 08:45:32 +0000633 err->tid = tid;
njn43c799e2003-04-08 00:08:52 +0000634 if (NULL == where)
sewardjadb102f2007-11-09 23:21:44 +0000635 err->where = VG_(record_ExeContext)( tid, 0 );
njn43c799e2003-04-08 00:08:52 +0000636 else
637 err->where = where;
njn1d6c4bc2002-11-21 13:38:08 +0000638
nethercote996901a2004-08-03 13:29:09 +0000639 /* Tool-relevant parts */
njn810086f2002-11-14 12:42:47 +0000640 err->ekind = ekind;
641 err->addr = a;
njn810086f2002-11-14 12:42:47 +0000642 err->extra = extra;
sewardja6022612003-07-24 23:50:17 +0000643 err->string = s;
644
njn25e49d8e72002-09-23 09:36:25 +0000645 /* sanity... */
njn72718642003-07-24 08:45:32 +0000646 vg_assert( tid < VG_N_THREADS );
njn25e49d8e72002-09-23 09:36:25 +0000647}
648
njn83f9e792005-06-11 05:04:09 +0000649
njn43c799e2003-04-08 00:08:52 +0000650
njn25e49d8e72002-09-23 09:36:25 +0000651/* Top-level entry point to the error management subsystem.
652 All detected errors are notified here; this routine decides if/when the
653 user should see the error. */
njn72718642003-07-24 08:45:32 +0000654void VG_(maybe_record_error) ( ThreadId tid,
njn25e49d8e72002-09-23 09:36:25 +0000655 ErrorKind ekind, Addr a, Char* s, void* extra )
656{
njn810086f2002-11-14 12:42:47 +0000657 Error err;
658 Error* p;
659 Error* p_prev;
njn43c799e2003-04-08 00:08:52 +0000660 UInt extra_size;
njn695c16e2005-03-27 03:40:28 +0000661 VgRes exe_res = Vg_MedRes;
662 static Bool stopping_message = False;
663 static Bool slowdown_message = False;
sewardjde4a1d02002-03-22 01:27:54 +0000664
njn14319cc2005-03-13 06:26:22 +0000665 /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
666 been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
sewardjf2537be2002-04-24 21:03:47 +0000667 have been found, just refuse to collect any more. This stops
668 the burden of the error-management system becoming excessive in
669 extremely buggy programs, although it does make it pretty
670 pointless to continue the Valgrind run after this point. */
sewardj2e432902002-06-13 20:44:00 +0000671 if (VG_(clo_error_limit)
njn695c16e2005-03-27 03:40:28 +0000672 && (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN
sewardj8a051722005-06-30 00:10:16 +0000673 || n_errs_found >= M_COLLECT_NO_ERRORS_AFTER_FOUND)
674 && !VG_(clo_xml)) {
sewardjde4a1d02002-03-22 01:27:54 +0000675 if (!stopping_message) {
sewardj738856f2009-07-15 14:48:32 +0000676 VG_(umsg)("\n");
sewardjf2537be2002-04-24 21:03:47 +0000677
njn695c16e2005-03-27 03:40:28 +0000678 if (n_errs_shown >= M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
sewardj738856f2009-07-15 14:48:32 +0000679 VG_(umsg)(
sewardjf2537be2002-04-24 21:03:47 +0000680 "More than %d different errors detected. "
sewardj738856f2009-07-15 14:48:32 +0000681 "I'm not reporting any more.\n",
njn14319cc2005-03-13 06:26:22 +0000682 M_COLLECT_NO_ERRORS_AFTER_SHOWN );
sewardjf2537be2002-04-24 21:03:47 +0000683 } else {
sewardj738856f2009-07-15 14:48:32 +0000684 VG_(umsg)(
sewardjf2537be2002-04-24 21:03:47 +0000685 "More than %d total errors detected. "
sewardj738856f2009-07-15 14:48:32 +0000686 "I'm not reporting any more.\n",
njn14319cc2005-03-13 06:26:22 +0000687 M_COLLECT_NO_ERRORS_AFTER_FOUND );
sewardjf2537be2002-04-24 21:03:47 +0000688 }
689
sewardj738856f2009-07-15 14:48:32 +0000690 VG_(umsg)("Final error counts will be inaccurate. "
691 "Go fix your program!\n");
692 VG_(umsg)("Rerun with --error-limit=no to disable "
693 "this cutoff. Note\n");
694 VG_(umsg)("that errors may occur in your program without "
695 "prior warning from\n");
696 VG_(umsg)("Valgrind, because errors are no longer "
697 "being displayed.\n");
698 VG_(umsg)("\n");
sewardjde4a1d02002-03-22 01:27:54 +0000699 stopping_message = True;
700 }
701 return;
702 }
703
sewardjdc873c02011-07-24 16:02:33 +0000704 /* Ignore it if error acquisition is disabled for this thread. */
705 { ThreadState* tst = VG_(get_ThreadState)(tid);
706 if (tst->err_disablement_level > 0)
707 return;
708 }
709
njn14319cc2005-03-13 06:26:22 +0000710 /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
sewardjde4a1d02002-03-22 01:27:54 +0000711 been found, be much more conservative about collecting new
712 ones. */
sewardj8a051722005-06-30 00:10:16 +0000713 if (n_errs_shown >= M_COLLECT_ERRORS_SLOWLY_AFTER
714 && !VG_(clo_xml)) {
njn25e49d8e72002-09-23 09:36:25 +0000715 exe_res = Vg_LowRes;
sewardjde4a1d02002-03-22 01:27:54 +0000716 if (!slowdown_message) {
sewardj738856f2009-07-15 14:48:32 +0000717 VG_(umsg)("\n");
718 VG_(umsg)("More than %d errors detected. Subsequent errors\n",
719 M_COLLECT_ERRORS_SLOWLY_AFTER);
720 VG_(umsg)("will still be recorded, but in less "
721 "detail than before.\n");
sewardjde4a1d02002-03-22 01:27:54 +0000722 slowdown_message = True;
723 }
724 }
725
njn25e49d8e72002-09-23 09:36:25 +0000726 /* Build ourselves the error */
njn72718642003-07-24 08:45:32 +0000727 construct_error ( &err, tid, ekind, a, s, extra, NULL );
sewardjde4a1d02002-03-22 01:27:54 +0000728
729 /* First, see if we've got an error record matching this one. */
sewardj8a7d4e42006-10-17 01:41:17 +0000730 em_errlist_searches++;
731 p = errors;
732 p_prev = NULL;
sewardjde4a1d02002-03-22 01:27:54 +0000733 while (p != NULL) {
sewardj8a7d4e42006-10-17 01:41:17 +0000734 em_errlist_cmps++;
njn810086f2002-11-14 12:42:47 +0000735 if (eq_Error(exe_res, p, &err)) {
sewardjde4a1d02002-03-22 01:27:54 +0000736 /* Found it. */
737 p->count++;
738 if (p->supp != NULL) {
739 /* Deal correctly with suppressed errors. */
740 p->supp->count++;
nethercotef2b11482004-08-02 12:36:01 +0000741 n_errs_suppressed++;
sewardjde4a1d02002-03-22 01:27:54 +0000742 } else {
nethercotef2b11482004-08-02 12:36:01 +0000743 n_errs_found++;
sewardjde4a1d02002-03-22 01:27:54 +0000744 }
745
746 /* Move p to the front of the list so that future searches
sewardj3b290482011-05-06 21:02:55 +0000747 for it are faster. It also allows to print the last
748 error (see VG_(show_last_error). */
sewardjde4a1d02002-03-22 01:27:54 +0000749 if (p_prev != NULL) {
750 vg_assert(p_prev->next == p);
njn695c16e2005-03-27 03:40:28 +0000751 p_prev->next = p->next;
752 p->next = errors;
753 errors = p;
sewardjde4a1d02002-03-22 01:27:54 +0000754 }
sewardj7ebf7c32003-07-24 21:29:40 +0000755
sewardjde4a1d02002-03-22 01:27:54 +0000756 return;
757 }
758 p_prev = p;
759 p = p->next;
760 }
761
762 /* Didn't see it. Copy and add. */
763
njn43c799e2003-04-08 00:08:52 +0000764 /* OK, we're really going to collect it. The context is on the stack and
765 will disappear shortly, so we must copy it. First do the main
njn02bc4b82005-05-15 17:28:26 +0000766 (non-'extra') part.
njn25e49d8e72002-09-23 09:36:25 +0000767
njn02bc4b82005-05-15 17:28:26 +0000768 Then VG_(tdict).tool_update_extra can update the 'extra' part. This
njn51d827b2005-05-09 01:02:08 +0000769 is for when there are more details to fill in which take time to work
770 out but don't affect our earlier decision to include the error -- by
njn25e49d8e72002-09-23 09:36:25 +0000771 postponing those details until now, we avoid the extra work in the
njn810086f2002-11-14 12:42:47 +0000772 case where we ignore the error. Ugly.
njn43c799e2003-04-08 00:08:52 +0000773
njn02bc4b82005-05-15 17:28:26 +0000774 Then, if there is an 'extra' part, copy it too, using the size that
njn51d827b2005-05-09 01:02:08 +0000775 VG_(tdict).tool_update_extra returned. Also allow for people using
776 the void* extra field for a scalar value like an integer.
njn43c799e2003-04-08 00:08:52 +0000777 */
778
779 /* copy main part */
sewardj9c606bd2008-09-18 18:12:50 +0000780 p = VG_(arena_malloc)(VG_AR_ERRORS, "errormgr.mre.1", sizeof(Error));
njn25e49d8e72002-09-23 09:36:25 +0000781 *p = err;
njn43c799e2003-04-08 00:08:52 +0000782
njn02bc4b82005-05-15 17:28:26 +0000783 /* update 'extra' */
sewardjb5f6f512005-03-10 23:59:00 +0000784 switch (ekind) {
njna86f29e2006-12-14 02:55:58 +0000785 //(example code, see comment on CoreSuppKind above)
786 //case ThreadErr:
787 // vg_assert(VG_(needs).core_errors);
788 // extra_size = <something>
789 // break;
sewardjb5f6f512005-03-10 23:59:00 +0000790 default:
791 vg_assert(VG_(needs).tool_errors);
njn51d827b2005-05-09 01:02:08 +0000792 extra_size = VG_TDICT_CALL(tool_update_extra, p);
sewardjb5f6f512005-03-10 23:59:00 +0000793 break;
794 }
njn43c799e2003-04-08 00:08:52 +0000795
njn02bc4b82005-05-15 17:28:26 +0000796 /* copy block pointed to by 'extra', if there is one */
sewardjb5f6f512005-03-10 23:59:00 +0000797 if (NULL != p->extra && 0 != extra_size) {
sewardj9c606bd2008-09-18 18:12:50 +0000798 void* new_extra = VG_(malloc)("errormgr.mre.2", extra_size);
sewardjb5f6f512005-03-10 23:59:00 +0000799 VG_(memcpy)(new_extra, p->extra, extra_size);
800 p->extra = new_extra;
njn43c799e2003-04-08 00:08:52 +0000801 }
802
njn695c16e2005-03-27 03:40:28 +0000803 p->next = errors;
njn25e49d8e72002-09-23 09:36:25 +0000804 p->supp = is_suppressible_error(&err);
njn695c16e2005-03-27 03:40:28 +0000805 errors = p;
sewardjde4a1d02002-03-22 01:27:54 +0000806 if (p->supp == NULL) {
philippebaf69642012-02-15 22:29:30 +0000807 /* update stats */
njn606a4ae2009-08-11 00:52:40 +0000808 n_err_contexts++;
nethercotef2b11482004-08-02 12:36:01 +0000809 n_errs_found++;
philippebaf69642012-02-15 22:29:30 +0000810 n_errs_shown++;
sewardj738856f2009-07-15 14:48:32 +0000811 /* Actually show the error; more complex than you might think. */
sewardj3b290482011-05-06 21:02:55 +0000812 pp_Error( p, /*allow_db_attach*/True, VG_(clo_xml) );
sewardjde4a1d02002-03-22 01:27:54 +0000813 } else {
njn606a4ae2009-08-11 00:52:40 +0000814 n_supp_contexts++;
nethercotef2b11482004-08-02 12:36:01 +0000815 n_errs_suppressed++;
sewardjde4a1d02002-03-22 01:27:54 +0000816 p->supp->count++;
817 }
818}
819
njn43c799e2003-04-08 00:08:52 +0000820/* Second top-level entry point to the error management subsystem, for
nethercote7cc9c232004-01-21 15:08:04 +0000821 errors that the tool wants to report immediately, eg. because they're
njn43c799e2003-04-08 00:08:52 +0000822 guaranteed to only happen once. This avoids all the recording and
823 comparing stuff. But they can be suppressed; returns True if it is
njn02bc4b82005-05-15 17:28:26 +0000824 suppressed. Bool 'print_error' dictates whether to print the error.
njn18afe5d2009-08-10 08:25:39 +0000825 Bool 'count_error' dictates whether to count the error in n_errs_found.
njn47363ab2003-04-21 13:24:40 +0000826*/
njn72718642003-07-24 08:45:32 +0000827Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
njn3e884182003-04-15 13:03:23 +0000828 void* extra, ExeContext* where, Bool print_error,
njn18afe5d2009-08-10 08:25:39 +0000829 Bool allow_db_attach, Bool count_error )
njn43c799e2003-04-08 00:08:52 +0000830{
njnfb289bc2007-01-12 23:59:50 +0000831 Error err;
832 Supp *su;
njn43c799e2003-04-08 00:08:52 +0000833
sewardjdc873c02011-07-24 16:02:33 +0000834 /* Ignore it if error acquisition is disabled for this thread. */
835 ThreadState* tst = VG_(get_ThreadState)(tid);
836 if (tst->err_disablement_level > 0)
837 return False; /* ignored, not suppressed */
838
njn43c799e2003-04-08 00:08:52 +0000839 /* Build ourselves the error */
njn72718642003-07-24 08:45:32 +0000840 construct_error ( &err, tid, ekind, a, s, extra, where );
njn43c799e2003-04-08 00:08:52 +0000841
842 /* Unless it's suppressed, we're going to show it. Don't need to make
843 a copy, because it's only temporary anyway.
844
njn02bc4b82005-05-15 17:28:26 +0000845 Then update the 'extra' part with VG_(tdict).tool_update_extra),
njn51d827b2005-05-09 01:02:08 +0000846 because that can have an affect on whether it's suppressed. Ignore
847 the size return value of VG_(tdict).tool_update_extra, because we're
njn02bc4b82005-05-15 17:28:26 +0000848 not copying 'extra'. */
njn51d827b2005-05-09 01:02:08 +0000849 (void)VG_TDICT_CALL(tool_update_extra, &err);
njn43c799e2003-04-08 00:08:52 +0000850
njnfb289bc2007-01-12 23:59:50 +0000851 su = is_suppressible_error(&err);
852 if (NULL == su) {
njn606a4ae2009-08-11 00:52:40 +0000853 if (count_error) {
njn18afe5d2009-08-10 08:25:39 +0000854 n_errs_found++;
njn606a4ae2009-08-11 00:52:40 +0000855 n_err_contexts++;
856 }
njn43c799e2003-04-08 00:08:52 +0000857
858 if (print_error) {
sewardj738856f2009-07-15 14:48:32 +0000859 /* update stats */
njnfb289bc2007-01-12 23:59:50 +0000860 n_errs_shown++;
philippebaf69642012-02-15 22:29:30 +0000861 /* Actually show the error; more complex than you might think. */
862 pp_Error(&err, allow_db_attach, VG_(clo_xml));
njn43c799e2003-04-08 00:08:52 +0000863 }
njn43c799e2003-04-08 00:08:52 +0000864 return False;
865
866 } else {
njn663ab792009-08-13 04:24:38 +0000867 if (count_error) {
868 n_errs_suppressed++;
869 n_supp_contexts++;
870 }
njnfb289bc2007-01-12 23:59:50 +0000871 su->count++;
njn43c799e2003-04-08 00:08:52 +0000872 return True;
873 }
874}
875
sewardjde4a1d02002-03-22 01:27:54 +0000876
sewardjde4a1d02002-03-22 01:27:54 +0000877/*------------------------------------------------------------*/
878/*--- Exported fns ---*/
879/*------------------------------------------------------------*/
880
sewardj71bc3cb2005-05-19 00:25:45 +0000881/* Show the used suppressions. Returns False if no suppression
882 got used. */
883static Bool show_used_suppressions ( void )
884{
885 Supp *su;
886 Bool any_supp;
887
sewardj7c9e57c2005-05-24 14:21:45 +0000888 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000889 VG_(printf_xml)("<suppcounts>\n");
sewardj7c9e57c2005-05-24 14:21:45 +0000890
sewardj71bc3cb2005-05-19 00:25:45 +0000891 any_supp = False;
892 for (su = suppressions; su != NULL; su = su->next) {
893 if (su->count <= 0)
894 continue;
sewardj71bc3cb2005-05-19 00:25:45 +0000895 if (VG_(clo_xml)) {
bartb3af9cf2011-10-06 19:08:37 +0000896 VG_(printf_xml)( " <pair>\n"
sewardj738856f2009-07-15 14:48:32 +0000897 " <count>%d</count>\n"
bartb3af9cf2011-10-06 19:08:37 +0000898 " <name>%pS</name>\n"
sewardj738856f2009-07-15 14:48:32 +0000899 " </pair>\n",
900 su->count, su->sname );
sewardj71bc3cb2005-05-19 00:25:45 +0000901 } else {
sewardj2d9e8742009-08-07 15:46:56 +0000902 // blank line before the first shown suppression, if any
903 if (!any_supp)
904 VG_(dmsg)("\n");
905 VG_(dmsg)("used_suppression: %6d %s\n", su->count, su->sname);
sewardj71bc3cb2005-05-19 00:25:45 +0000906 }
sewardj2d9e8742009-08-07 15:46:56 +0000907 any_supp = True;
sewardj71bc3cb2005-05-19 00:25:45 +0000908 }
909
sewardj7c9e57c2005-05-24 14:21:45 +0000910 if (VG_(clo_xml))
sewardj738856f2009-07-15 14:48:32 +0000911 VG_(printf_xml)("</suppcounts>\n");
sewardj7c9e57c2005-05-24 14:21:45 +0000912
sewardj71bc3cb2005-05-19 00:25:45 +0000913 return any_supp;
914}
915
sewardj9f297ca2005-05-20 02:29:52 +0000916/* Show all the errors that occurred, and possibly also the
917 suppressions used. */
sewardj3b290482011-05-06 21:02:55 +0000918void VG_(show_all_errors) ( Int verbosity, Bool xml )
sewardjde4a1d02002-03-22 01:27:54 +0000919{
njn810086f2002-11-14 12:42:47 +0000920 Int i, n_min;
njn810086f2002-11-14 12:42:47 +0000921 Error *p, *p_min;
njn810086f2002-11-14 12:42:47 +0000922 Bool any_supp;
sewardjde4a1d02002-03-22 01:27:54 +0000923
sewardj3b290482011-05-06 21:02:55 +0000924 if (verbosity == 0)
sewardjde4a1d02002-03-22 01:27:54 +0000925 return;
926
njn606a4ae2009-08-11 00:52:40 +0000927 /* If we're printing XML, just show the suppressions and stop. */
sewardj3b290482011-05-06 21:02:55 +0000928 if (xml) {
sewardj71bc3cb2005-05-19 00:25:45 +0000929 (void)show_used_suppressions();
930 return;
931 }
932
933 /* We only get here if not printing XML. */
sewardj738856f2009-07-15 14:48:32 +0000934 VG_(umsg)("ERROR SUMMARY: "
935 "%d errors from %d contexts (suppressed: %d from %d)\n",
936 n_errs_found, n_err_contexts,
937 n_errs_suppressed, n_supp_contexts );
sewardjde4a1d02002-03-22 01:27:54 +0000938
sewardj3b290482011-05-06 21:02:55 +0000939 if (verbosity <= 1)
sewardjde4a1d02002-03-22 01:27:54 +0000940 return;
941
sewardj2d9e8742009-08-07 15:46:56 +0000942 // We do the following only at -v or above, and only in non-XML
943 // mode
944
sewardj3b290482011-05-06 21:02:55 +0000945 /* Print the contexts in order of increasing error count.
946 Once an error is shown, we add a huge value to its count to filter it
947 out. After having shown all errors, we reset count to the original value. */
sewardjde4a1d02002-03-22 01:27:54 +0000948 for (i = 0; i < n_err_contexts; i++) {
949 n_min = (1 << 30) - 1;
950 p_min = NULL;
njn695c16e2005-03-27 03:40:28 +0000951 for (p = errors; p != NULL; p = p->next) {
sewardjde4a1d02002-03-22 01:27:54 +0000952 if (p->supp != NULL) continue;
953 if (p->count < n_min) {
954 n_min = p->count;
955 p_min = p;
956 }
957 }
njn663ab792009-08-13 04:24:38 +0000958 // XXX: this isn't right. See bug 203651.
959 if (p_min == NULL) continue; //VG_(tool_panic)("show_all_errors()");
sewardjde4a1d02002-03-22 01:27:54 +0000960
sewardj738856f2009-07-15 14:48:32 +0000961 VG_(umsg)("\n");
962 VG_(umsg)("%d errors in context %d of %d:\n",
963 p_min->count, i+1, n_err_contexts);
sewardj3b290482011-05-06 21:02:55 +0000964 pp_Error( p_min, False/*allow_db_attach*/, False /* xml */ );
sewardj738856f2009-07-15 14:48:32 +0000965
966 // We're not printing XML -- we'd have exited above if so.
sewardj3b290482011-05-06 21:02:55 +0000967 vg_assert(! xml);
sewardjde4a1d02002-03-22 01:27:54 +0000968
969 if ((i+1 == VG_(clo_dump_error))) {
sewardj7cf4e6b2008-05-01 20:24:26 +0000970 StackTrace ips = VG_(get_ExeContext_StackTrace)(p_min->where);
sewardjfa8ec112005-01-19 11:55:34 +0000971 VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debugging*/,
njn394213a2005-06-19 18:38:24 +0000972 ips[0], /*debugging*/True, 0xFE/*verbosity*/,
sewardj0ec07f32006-01-12 12:32:32 +0000973 /*bbs_done*/0,
974 /*allow redir?*/True);
sewardjde4a1d02002-03-22 01:27:54 +0000975 }
976
sewardj3b290482011-05-06 21:02:55 +0000977 p_min->count = p_min->count + (1 << 30);
sewardjde4a1d02002-03-22 01:27:54 +0000978 }
979
sewardj3b290482011-05-06 21:02:55 +0000980 /* reset the counts, otherwise a 2nd call does not show anything anymore */
981 for (p = errors; p != NULL; p = p->next) {
982 if (p->count >= (1 << 30))
983 p->count = p->count - (1 << 30);
984 }
985
986
sewardj71bc3cb2005-05-19 00:25:45 +0000987 any_supp = show_used_suppressions();
sewardjde4a1d02002-03-22 01:27:54 +0000988
sewardj2d9e8742009-08-07 15:46:56 +0000989 if (any_supp)
sewardj738856f2009-07-15 14:48:32 +0000990 VG_(umsg)("\n");
sewardj2d9e8742009-08-07 15:46:56 +0000991 // reprint this, so users don't have to scroll way up to find
992 // the first printing
993 VG_(umsg)("ERROR SUMMARY: "
994 "%d errors from %d contexts (suppressed: %d from %d)\n",
995 n_errs_found, n_err_contexts, n_errs_suppressed,
996 n_supp_contexts );
sewardjde4a1d02002-03-22 01:27:54 +0000997}
998
sewardj3b290482011-05-06 21:02:55 +0000999void VG_(show_last_error) ( void )
1000{
1001 if (n_err_contexts == 0) {
1002 VG_(umsg)("No errors yet\n");
1003 return;
1004 }
1005
1006 pp_Error( errors, False/*allow_db_attach*/, False/*xml*/ );
1007}
1008
sewardj9f297ca2005-05-20 02:29:52 +00001009
1010/* Show occurrence counts of all errors, in XML form. */
1011void VG_(show_error_counts_as_XML) ( void )
1012{
1013 Error* err;
sewardj738856f2009-07-15 14:48:32 +00001014 VG_(printf_xml)("<errorcounts>\n");
sewardj9f297ca2005-05-20 02:29:52 +00001015 for (err = errors; err != NULL; err = err->next) {
1016 if (err->supp != NULL)
1017 continue;
1018 if (err->count <= 0)
1019 continue;
sewardj738856f2009-07-15 14:48:32 +00001020 VG_(printf_xml)(" <pair>\n");
1021 VG_(printf_xml)(" <count>%d</count>\n", err->count);
1022 VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
1023 VG_(printf_xml)(" </pair>\n");
sewardj9f297ca2005-05-20 02:29:52 +00001024 }
sewardj738856f2009-07-15 14:48:32 +00001025 VG_(printf_xml)("</errorcounts>\n");
njnb6267bd2009-08-12 00:14:16 +00001026 VG_(printf_xml)("\n");
sewardj9f297ca2005-05-20 02:29:52 +00001027}
1028
1029
sewardjde4a1d02002-03-22 01:27:54 +00001030/*------------------------------------------------------------*/
sewardjd7a02db2008-12-12 08:07:49 +00001031/*--- Suppression parsing ---*/
sewardjde4a1d02002-03-22 01:27:54 +00001032/*------------------------------------------------------------*/
1033
sewardj8a7d4e42006-10-17 01:41:17 +00001034/* Get the next char from fd into *out_buf. Returns 1 if success,
1035 0 if eof or < 0 if error. */
1036
1037static Int get_char ( Int fd, Char* out_buf )
1038{
1039 Int r;
sewardj89c5bd82008-10-23 10:15:37 +00001040 static Char buf[256];
sewardj8a7d4e42006-10-17 01:41:17 +00001041 static Int buf_size = 0;
1042 static Int buf_used = 0;
sewardj89c5bd82008-10-23 10:15:37 +00001043 vg_assert(buf_size >= 0 && buf_size <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001044 vg_assert(buf_used >= 0 && buf_used <= buf_size);
1045 if (buf_used == buf_size) {
sewardj89c5bd82008-10-23 10:15:37 +00001046 r = VG_(read)(fd, buf, 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001047 if (r < 0) return r; /* read failed */
sewardj89c5bd82008-10-23 10:15:37 +00001048 vg_assert(r >= 0 && r <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001049 buf_size = r;
1050 buf_used = 0;
1051 }
1052 if (buf_size == 0)
1053 return 0; /* eof */
sewardj89c5bd82008-10-23 10:15:37 +00001054 vg_assert(buf_size >= 0 && buf_size <= 256);
sewardj8a7d4e42006-10-17 01:41:17 +00001055 vg_assert(buf_used >= 0 && buf_used < buf_size);
1056 *out_buf = buf[buf_used];
1057 buf_used++;
1058 return 1;
1059}
1060
bart050eec52009-07-27 12:03:03 +00001061Bool VG_(get_line) ( Int fd, Char** bufpp, SizeT* nBufp, Int* lineno )
sewardjde4a1d02002-03-22 01:27:54 +00001062{
njn35db56c2009-07-24 07:38:29 +00001063 Char* buf = *bufpp;
1064 SizeT nBuf = *nBufp;
1065 Char ch;
1066 Int n, i;
sewardjde4a1d02002-03-22 01:27:54 +00001067 while (True) {
1068 /* First, read until a non-blank char appears. */
1069 while (True) {
sewardj8a7d4e42006-10-17 01:41:17 +00001070 n = get_char(fd, &ch);
njn0c0f32a2005-03-26 04:14:01 +00001071 if (n == 1 && !VG_(isspace)(ch)) break;
bart050eec52009-07-27 12:03:03 +00001072 if (n == 1 && ch == '\n' && lineno)
1073 (*lineno)++;
sewardj8a7d4e42006-10-17 01:41:17 +00001074 if (n <= 0) return True;
sewardjde4a1d02002-03-22 01:27:54 +00001075 }
1076
1077 /* Now, read the line into buf. */
1078 i = 0;
1079 buf[i++] = ch; buf[i] = 0;
1080 while (True) {
sewardj8a7d4e42006-10-17 01:41:17 +00001081 n = get_char(fd, &ch);
1082 if (n <= 0) return False; /* the next call will return True */
bart050eec52009-07-27 12:03:03 +00001083 if (ch == '\n' && lineno)
1084 (*lineno)++;
sewardjde4a1d02002-03-22 01:27:54 +00001085 if (ch == '\n') break;
njn35db56c2009-07-24 07:38:29 +00001086 if (i > 0 && i == nBuf-1) {
1087 *nBufp = nBuf = nBuf * 2;
1088 #define RIDICULOUS 100000
1089 vg_assert2(nBuf < RIDICULOUS, // Just a sanity check, really.
1090 "VG_(get_line): line longer than %d chars, aborting\n",
1091 RIDICULOUS);
1092 *bufpp = buf = VG_(realloc)("errormgr.get_line.1", buf, nBuf);
1093 }
sewardjde4a1d02002-03-22 01:27:54 +00001094 buf[i++] = ch; buf[i] = 0;
1095 }
njn0c0f32a2005-03-26 04:14:01 +00001096 while (i > 1 && VG_(isspace)(buf[i-1])) {
sewardjde4a1d02002-03-22 01:27:54 +00001097 i--; buf[i] = 0;
1098 };
1099
njn02bc4b82005-05-15 17:28:26 +00001100 /* VG_(printf)("The line is '%s'\n", buf); */
sewardjde4a1d02002-03-22 01:27:54 +00001101 /* Ok, we have a line. If a non-comment line, return.
1102 If a comment line, start all over again. */
1103 if (buf[0] != '#') return False;
1104 }
1105}
1106
1107
philippe2c5c05e2012-07-26 21:37:36 +00001108/* True if s contains no wildcard (?, *) characters. */
1109static Bool is_simple_str (Char *s)
1110{
1111 int i;
1112 while (*s) {
1113 if (*s == '?' || *s == '*')
1114 return False;
1115 s++;
1116 }
1117 return True;
1118}
1119
philippe7d69fd92012-02-26 21:26:00 +00001120/* buf contains the raw name of a caller, supposedly either
sewardjde4a1d02002-03-22 01:27:54 +00001121 fun:some_function_name or
philippe7d69fd92012-02-26 21:26:00 +00001122 obj:some_object_name or
1123 ...
1124 Set p->ty and p->name accordingly.
1125 p->name is allocated and set to the string
1126 after the descriptor (fun: or obj:) part.
sewardjde4a1d02002-03-22 01:27:54 +00001127 Returns False if failed.
1128*/
philippe7d69fd92012-02-26 21:26:00 +00001129static Bool setLocationTy ( SuppLoc* p, Char *buf )
sewardjde4a1d02002-03-22 01:27:54 +00001130{
philippe7d69fd92012-02-26 21:26:00 +00001131 if (VG_(strncmp)(buf, "fun:", 4) == 0) {
1132 p->name = VG_(arena_strdup)(VG_AR_CORE,
1133 "errormgr.sLTy.1", buf+4);
philippe2c5c05e2012-07-26 21:37:36 +00001134 p->name_is_simple_str = is_simple_str (p->name);
sewardjb5f6f512005-03-10 23:59:00 +00001135 p->ty = FunName;
sewardjde4a1d02002-03-22 01:27:54 +00001136 return True;
1137 }
philippe7d69fd92012-02-26 21:26:00 +00001138 if (VG_(strncmp)(buf, "obj:", 4) == 0) {
1139 p->name = VG_(arena_strdup)(VG_AR_CORE,
1140 "errormgr.sLTy.2", buf+4);
philippe2c5c05e2012-07-26 21:37:36 +00001141 p->name_is_simple_str = is_simple_str (p->name);
sewardjb5f6f512005-03-10 23:59:00 +00001142 p->ty = ObjName;
sewardjde4a1d02002-03-22 01:27:54 +00001143 return True;
1144 }
philippe7d69fd92012-02-26 21:26:00 +00001145 if (VG_(strcmp)(buf, "...") == 0) {
sewardj5e519302008-11-03 23:10:25 +00001146 p->name = NULL;
philippe2c5c05e2012-07-26 21:37:36 +00001147 p->name_is_simple_str = False;
sewardj5e519302008-11-03 23:10:25 +00001148 p->ty = DotDotDot;
1149 return True;
1150 }
1151 VG_(printf)("location should be \"...\", or should start "
1152 "with \"fun:\" or \"obj:\"\n");
sewardjde4a1d02002-03-22 01:27:54 +00001153 return False;
1154}
1155
1156
nethercote7cc9c232004-01-21 15:08:04 +00001157/* Look for "tool" in a string like "tool1,tool2,tool3" */
sewardjd7a02db2008-12-12 08:07:49 +00001158static Bool tool_name_present(Char *name, Char *names)
njn11cc9252002-10-07 14:42:59 +00001159{
1160 Bool found;
1161 Char *s = NULL; /* Shut gcc up */
1162 Int len = VG_(strlen)(name);
1163
1164 found = (NULL != (s = VG_(strstr)(names, name)) &&
1165 (s == names || *(s-1) == ',') &&
1166 (*(s+len) == ',' || *(s+len) == '\0')
1167 );
1168
1169 return found;
1170}
1171
njn695c16e2005-03-27 03:40:28 +00001172/* Read suppressions from the file specified in VG_(clo_suppressions)
sewardjde4a1d02002-03-22 01:27:54 +00001173 and place them in the suppressions list. If there's any difficulty
1174 doing this, just give up -- there's no point in trying to recover.
1175*/
sewardjde4a1d02002-03-22 01:27:54 +00001176static void load_one_suppressions_file ( Char* filename )
1177{
sewardj92645592005-07-23 09:18:34 +00001178 SysRes sres;
sewardj5e519302008-11-03 23:10:25 +00001179 Int fd, i, j, lineno = 0;
sewardj92645592005-07-23 09:18:34 +00001180 Bool eof;
njn35db56c2009-07-24 07:38:29 +00001181 SizeT nBuf = 200;
1182 Char* buf = VG_(malloc)("errormgr.losf.1", nBuf);
sewardj92645592005-07-23 09:18:34 +00001183 Char* tool_names;
1184 Char* supp_name;
1185 Char* err_str = NULL;
sewardjb5f6f512005-03-10 23:59:00 +00001186 SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
njnc40c3a82002-10-02 11:02:27 +00001187
njncc37d2e2009-06-24 03:49:19 +00001188 // Check it's not a directory.
1189 if (VG_(is_dir)( filename )) {
1190 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001191 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001192 VG_(umsg)("FATAL: suppressions file \"%s\" is a directory\n", filename );
njncc37d2e2009-06-24 03:49:19 +00001193 VG_(exit)(1);
1194 }
1195
1196 // Open the suppression file.
sewardj92645592005-07-23 09:18:34 +00001197 sres = VG_(open)( filename, VKI_O_RDONLY, 0 );
njncda2f0f2009-05-18 02:12:08 +00001198 if (sr_isError(sres)) {
sewardjf349d552005-11-14 17:01:01 +00001199 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001200 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001201 VG_(umsg)("FATAL: can't open suppressions file \"%s\"\n", filename );
sewardjde4a1d02002-03-22 01:27:54 +00001202 VG_(exit)(1);
1203 }
njncda2f0f2009-05-18 02:12:08 +00001204 fd = sr_Res(sres);
sewardjde4a1d02002-03-22 01:27:54 +00001205
sewardj92645592005-07-23 09:18:34 +00001206# define BOMB(S) { err_str = S; goto syntax_error; }
sewardjb5f6f512005-03-10 23:59:00 +00001207
sewardjde4a1d02002-03-22 01:27:54 +00001208 while (True) {
nethercote7cc9c232004-01-21 15:08:04 +00001209 /* Assign and initialise the two suppression halves (core and tool) */
njn810086f2002-11-14 12:42:47 +00001210 Supp* supp;
sewardj9c606bd2008-09-18 18:12:50 +00001211 supp = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.1",
1212 sizeof(Supp));
sewardjde4a1d02002-03-22 01:27:54 +00001213 supp->count = 0;
sewardjb5f6f512005-03-10 23:59:00 +00001214
1215 // Initialise temporary reading-in buffer.
1216 for (i = 0; i < VG_MAX_SUPP_CALLERS; i++) {
1217 tmp_callers[i].ty = NoName;
philippe2c5c05e2012-07-26 21:37:36 +00001218 tmp_callers[i].name_is_simple_str = False;
sewardjb5f6f512005-03-10 23:59:00 +00001219 tmp_callers[i].name = NULL;
1220 }
1221
njn810086f2002-11-14 12:42:47 +00001222 supp->string = supp->extra = NULL;
sewardjde4a1d02002-03-22 01:27:54 +00001223
bart050eec52009-07-27 12:03:03 +00001224 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
philippe7d69fd92012-02-26 21:26:00 +00001225 if (eof) {
1226 VG_(arena_free)(VG_AR_CORE, supp);
1227 break;
1228 }
sewardjde4a1d02002-03-22 01:27:54 +00001229
sewardjb5f6f512005-03-10 23:59:00 +00001230 if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
sewardjde4a1d02002-03-22 01:27:54 +00001231
bart050eec52009-07-27 12:03:03 +00001232 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001233
1234 if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
1235
sewardj9c606bd2008-09-18 18:12:50 +00001236 supp->sname = VG_(arena_strdup)(VG_AR_CORE, "errormgr.losf.2", buf);
sewardjde4a1d02002-03-22 01:27:54 +00001237
bart050eec52009-07-27 12:03:03 +00001238 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
njn25e49d8e72002-09-23 09:36:25 +00001239
sewardjb5f6f512005-03-10 23:59:00 +00001240 if (eof) BOMB("unexpected end-of-file");
sewardjde4a1d02002-03-22 01:27:54 +00001241
njn94065fd2004-11-22 19:26:27 +00001242 /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
njnc40c3a82002-10-02 11:02:27 +00001243 i = 0;
1244 while (True) {
1245 if (buf[i] == ':') break;
sewardjb5f6f512005-03-10 23:59:00 +00001246 if (buf[i] == '\0') BOMB("malformed 'tool1,tool2,...:supp' line");
njnc40c3a82002-10-02 11:02:27 +00001247 i++;
njn25e49d8e72002-09-23 09:36:25 +00001248 }
njnc40c3a82002-10-02 11:02:27 +00001249 buf[i] = '\0'; /* Replace ':', splitting into two strings */
1250
nethercote7cc9c232004-01-21 15:08:04 +00001251 tool_names = & buf[0];
njn11cc9252002-10-07 14:42:59 +00001252 supp_name = & buf[i+1];
njnc40c3a82002-10-02 11:02:27 +00001253
nethercote7cc9c232004-01-21 15:08:04 +00001254 if (VG_(needs).core_errors && tool_name_present("core", tool_names))
njnc40c3a82002-10-02 11:02:27 +00001255 {
sewardjb5f6f512005-03-10 23:59:00 +00001256 // A core suppression
njna86f29e2006-12-14 02:55:58 +00001257 //(example code, see comment on CoreSuppKind above)
1258 //if (VG_STREQ(supp_name, "Thread"))
1259 // supp->skind = ThreadSupp;
1260 //else
sewardjb5f6f512005-03-10 23:59:00 +00001261 BOMB("unknown core suppression type");
njnc40c3a82002-10-02 11:02:27 +00001262 }
njn95ec8702004-11-22 16:46:13 +00001263 else if (VG_(needs).tool_errors &&
nethercote7cc9c232004-01-21 15:08:04 +00001264 tool_name_present(VG_(details).name, tool_names))
njnc40c3a82002-10-02 11:02:27 +00001265 {
sewardjb5f6f512005-03-10 23:59:00 +00001266 // A tool suppression
njn51d827b2005-05-09 01:02:08 +00001267 if (VG_TDICT_CALL(tool_recognised_suppression, supp_name, supp)) {
njn810086f2002-11-14 12:42:47 +00001268 /* Do nothing, function fills in supp->skind */
sewardjb5f6f512005-03-10 23:59:00 +00001269 } else {
1270 BOMB("unknown tool suppression type");
1271 }
njnc40c3a82002-10-02 11:02:27 +00001272 }
njn25e49d8e72002-09-23 09:36:25 +00001273 else {
sewardjb5f6f512005-03-10 23:59:00 +00001274 // Ignore rest of suppression
njn25e49d8e72002-09-23 09:36:25 +00001275 while (True) {
bart050eec52009-07-27 12:03:03 +00001276 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001277 if (eof) BOMB("unexpected end-of-file");
njn43c799e2003-04-08 00:08:52 +00001278 if (VG_STREQ(buf, "}"))
njn25e49d8e72002-09-23 09:36:25 +00001279 break;
1280 }
philippe7d69fd92012-02-26 21:26:00 +00001281 VG_(arena_free)(VG_AR_CORE, supp->sname);
1282 VG_(arena_free)(VG_AR_CORE, supp);
njn25e49d8e72002-09-23 09:36:25 +00001283 continue;
sewardjde4a1d02002-03-22 01:27:54 +00001284 }
1285
njn95ec8702004-11-22 16:46:13 +00001286 if (VG_(needs).tool_errors &&
sewardjd7a02db2008-12-12 08:07:49 +00001287 !VG_TDICT_CALL(tool_read_extra_suppression_info,
njn35db56c2009-07-24 07:38:29 +00001288 fd, &buf, &nBuf, supp))
sewardjb5f6f512005-03-10 23:59:00 +00001289 {
1290 BOMB("bad or missing extra suppression info");
sewardjde4a1d02002-03-22 01:27:54 +00001291 }
1292
sewardj5e519302008-11-03 23:10:25 +00001293 /* the main frame-descriptor reading loop */
sewardjb5f6f512005-03-10 23:59:00 +00001294 i = 0;
1295 while (True) {
bart050eec52009-07-27 12:03:03 +00001296 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001297 if (eof)
1298 BOMB("unexpected end-of-file");
1299 if (VG_STREQ(buf, "}")) {
1300 if (i > 0) {
1301 break;
1302 } else {
1303 BOMB("missing stack trace");
1304 }
1305 }
1306 if (i == VG_MAX_SUPP_CALLERS)
1307 BOMB("too many callers in stack trace");
1308 if (i > 0 && i >= VG_(clo_backtrace_size))
1309 break;
philippe7d69fd92012-02-26 21:26:00 +00001310 if (!setLocationTy(&(tmp_callers[i]), buf))
sewardj5e519302008-11-03 23:10:25 +00001311 BOMB("location should be \"...\", or should start "
1312 "with \"fun:\" or \"obj:\"");
sewardjb5f6f512005-03-10 23:59:00 +00001313 i++;
1314 }
1315
1316 // If the num callers is >= VG_(clo_backtrace_size), ignore any extra
1317 // lines and grab the '}'.
sewardj57a8f5f2003-07-06 01:40:11 +00001318 if (!VG_STREQ(buf, "}")) {
sewardjb5f6f512005-03-10 23:59:00 +00001319 do {
bart050eec52009-07-27 12:03:03 +00001320 eof = VG_(get_line) ( fd, &buf, &nBuf, &lineno );
sewardjb5f6f512005-03-10 23:59:00 +00001321 } while (!eof && !VG_STREQ(buf, "}"));
1322 }
1323
sewardj5e519302008-11-03 23:10:25 +00001324 // Reject entries which are entirely composed of frame
1325 // level wildcards.
1326 vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
1327 for (j = 0; j < i; j++) {
1328 if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
1329 break;
1330 vg_assert(tmp_callers[j].ty == DotDotDot);
1331 }
1332 vg_assert(j >= 0 && j <= i);
1333 if (j == i) {
1334 // we didn't find any non-"..." entries
1335 BOMB("suppression must contain at least one location "
1336 "line which is not \"...\"");
1337 }
1338
sewardjb5f6f512005-03-10 23:59:00 +00001339 // Copy tmp_callers[] into supp->callers[]
1340 supp->n_callers = i;
sewardj9c606bd2008-09-18 18:12:50 +00001341 supp->callers = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.4",
1342 i*sizeof(SuppLoc));
sewardjb5f6f512005-03-10 23:59:00 +00001343 for (i = 0; i < supp->n_callers; i++) {
1344 supp->callers[i] = tmp_callers[i];
sewardj57a8f5f2003-07-06 01:40:11 +00001345 }
1346
njn695c16e2005-03-27 03:40:28 +00001347 supp->next = suppressions;
1348 suppressions = supp;
sewardjde4a1d02002-03-22 01:27:54 +00001349 }
njn35db56c2009-07-24 07:38:29 +00001350 VG_(free)(buf);
sewardjde4a1d02002-03-22 01:27:54 +00001351 VG_(close)(fd);
1352 return;
1353
1354 syntax_error:
sewardjf349d552005-11-14 17:01:01 +00001355 if (VG_(clo_xml))
sewardj09361bf2011-01-28 00:19:25 +00001356 VG_(printf_xml)("</valgrindoutput>\n");
sewardj738856f2009-07-15 14:48:32 +00001357 VG_(umsg)("FATAL: in suppressions file \"%s\" near line %d:\n",
njn6f74a7e2009-03-12 00:06:45 +00001358 filename, lineno );
sewardj738856f2009-07-15 14:48:32 +00001359 VG_(umsg)(" %s\n", err_str );
sewardjb5f6f512005-03-10 23:59:00 +00001360
sewardjde4a1d02002-03-22 01:27:54 +00001361 VG_(close)(fd);
sewardj738856f2009-07-15 14:48:32 +00001362 VG_(umsg)("exiting now.\n");
nethercote8ed8a892004-11-08 13:24:25 +00001363 VG_(exit)(1);
sewardjde4a1d02002-03-22 01:27:54 +00001364
sewardjb5f6f512005-03-10 23:59:00 +00001365# undef BOMB
sewardjde4a1d02002-03-22 01:27:54 +00001366}
1367
1368
1369void VG_(load_suppressions) ( void )
1370{
1371 Int i;
njn695c16e2005-03-27 03:40:28 +00001372 suppressions = NULL;
sewardjde4a1d02002-03-22 01:27:54 +00001373 for (i = 0; i < VG_(clo_n_suppressions); i++) {
1374 if (VG_(clo_verbosity) > 1) {
sewardj738856f2009-07-15 14:48:32 +00001375 VG_(dmsg)("Reading suppressions file: %s\n",
1376 VG_(clo_suppressions)[i] );
sewardjde4a1d02002-03-22 01:27:54 +00001377 }
1378 load_one_suppressions_file( VG_(clo_suppressions)[i] );
1379 }
1380}
1381
sewardjd7a02db2008-12-12 08:07:49 +00001382
1383/*------------------------------------------------------------*/
1384/*--- Matching errors to suppressions ---*/
1385/*------------------------------------------------------------*/
1386
1387/* Parameterising functions for the use of VG_(generic_match) in
1388 suppression-vs-error matching. The suppression frames (SuppLoc)
1389 play the role of 'pattern'-element, and the error frames (IPs,
1390 hence simply Addrs) play the role of 'input'. In short then, we're
1391 matching a sequence of Addrs against a pattern composed of a
1392 sequence of SuppLocs.
1393*/
1394static Bool supploc_IsStar ( void* supplocV )
1395{
1396 SuppLoc* supploc = (SuppLoc*)supplocV;
1397 return supploc->ty == DotDotDot;
1398}
1399
1400static Bool supploc_IsQuery ( void* supplocV )
1401{
1402 return False; /* there's no '?' equivalent in the supp syntax */
1403}
1404
1405static Bool supp_pattEQinp ( void* supplocV, void* addrV )
1406{
1407 SuppLoc* supploc = (SuppLoc*)supplocV; /* PATTERN */
1408 Addr ip = *(Addr*)addrV; /* INPUT */
1409
1410 Char caller_name[ERRTXT_LEN];
1411 caller_name[0] = 0;
1412
1413 /* So, does this IP address match this suppression-line? */
1414 switch (supploc->ty) {
1415 case DotDotDot:
1416 /* supp_pattEQinp is a callback from VG_(generic_match). As
1417 per the spec thereof (see include/pub_tool_seqmatch.h), we
1418 should never get called with a pattern value for which the
1419 _IsStar or _IsQuery function would return True. Hence
1420 this can't happen. */
1421 vg_assert(0);
1422 case ObjName:
1423 /* Get the object name into 'caller_name', or "???"
1424 if unknown. */
1425 if (!VG_(get_objname)(ip, caller_name, ERRTXT_LEN))
1426 VG_(strcpy)(caller_name, "???");
1427 break;
1428 case FunName:
1429 /* Get the function name into 'caller_name', or "???"
1430 if unknown. */
njn6b7611b2009-02-11 06:06:10 +00001431 // Nb: C++-mangled names are used in suppressions. Do, though,
sewardjd7a02db2008-12-12 08:07:49 +00001432 // Z-demangle them, since otherwise it's possible to wind
1433 // up comparing "malloc" in the suppression against
1434 // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
1435 // two of them need to be made to match.
njn6b7611b2009-02-11 06:06:10 +00001436 if (!VG_(get_fnname_no_cxx_demangle)(ip, caller_name, ERRTXT_LEN))
sewardjd7a02db2008-12-12 08:07:49 +00001437 VG_(strcpy)(caller_name, "???");
1438 break;
1439 default:
1440 vg_assert(0);
1441 }
1442
1443 /* So now we have the function or object name in caller_name, and
1444 the pattern (at the character level) to match against is in
1445 supploc->name. Hence (and leading to a re-entrant call of
philippe2c5c05e2012-07-26 21:37:36 +00001446 VG_(generic_match) if there is a wildcard character): */
1447 if (supploc->name_is_simple_str)
1448 return VG_(strcmp) (supploc->name, caller_name) == 0;
1449 else
1450 return VG_(string_match)(supploc->name, caller_name);
sewardjd7a02db2008-12-12 08:07:49 +00001451}
1452
1453/////////////////////////////////////////////////////
1454
1455static Bool supp_matches_callers(Error* err, Supp* su)
1456{
1457 /* Unwrap the args and set up the correct parameterisation of
1458 VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
1459 supp_pattEQinp. */
1460 /* note, StackTrace === Addr* */
1461 StackTrace ips = VG_(get_ExeContext_StackTrace)(err->where);
1462 UWord n_ips = VG_(get_ExeContext_n_ips)(err->where);
1463 SuppLoc* supps = su->callers;
1464 UWord n_supps = su->n_callers;
1465 UWord szbPatt = sizeof(SuppLoc);
1466 UWord szbInput = sizeof(Addr);
1467 Bool matchAll = False; /* we just want to match a prefix */
1468 return
1469 VG_(generic_match)(
1470 matchAll,
1471 /*PATT*/supps, szbPatt, n_supps, 0/*initial Ix*/,
1472 /*INPUT*/ips, szbInput, n_ips, 0/*initial Ix*/,
1473 supploc_IsStar, supploc_IsQuery, supp_pattEQinp
1474 );
1475}
1476
1477/////////////////////////////////////////////////////
1478
sewardjb5f6f512005-03-10 23:59:00 +00001479static
njn810086f2002-11-14 12:42:47 +00001480Bool supp_matches_error(Supp* su, Error* err)
njn25e49d8e72002-09-23 09:36:25 +00001481{
njn810086f2002-11-14 12:42:47 +00001482 switch (su->skind) {
njna86f29e2006-12-14 02:55:58 +00001483 //(example code, see comment on CoreSuppKind above)
1484 //case ThreadSupp:
1485 // return (err->ekind == ThreadErr);
njn25e49d8e72002-09-23 09:36:25 +00001486 default:
njn95ec8702004-11-22 16:46:13 +00001487 if (VG_(needs).tool_errors) {
njn51d827b2005-05-09 01:02:08 +00001488 return VG_TDICT_CALL(tool_error_matches_suppression, err, su);
njn25e49d8e72002-09-23 09:36:25 +00001489 } else {
1490 VG_(printf)(
njn95ec8702004-11-22 16:46:13 +00001491 "\nUnhandled suppression type: %u. VG_(needs).tool_errors\n"
njn25e49d8e72002-09-23 09:36:25 +00001492 "probably needs to be set.\n",
njn810086f2002-11-14 12:42:47 +00001493 err->ekind);
njn67993252004-11-22 18:02:32 +00001494 VG_(tool_panic)("unhandled suppression type");
njn25e49d8e72002-09-23 09:36:25 +00001495 }
1496 }
1497}
1498
sewardjd7a02db2008-12-12 08:07:49 +00001499/////////////////////////////////////////////////////
sewardj5e519302008-11-03 23:10:25 +00001500
njn810086f2002-11-14 12:42:47 +00001501/* Does an error context match a suppression? ie is this a suppressible
1502 error? If so, return a pointer to the Supp record, otherwise NULL.
njn25e49d8e72002-09-23 09:36:25 +00001503 Tries to minimise the number of symbol searches since they are expensive.
sewardjde4a1d02002-03-22 01:27:54 +00001504*/
njn810086f2002-11-14 12:42:47 +00001505static Supp* is_suppressible_error ( Error* err )
sewardjde4a1d02002-03-22 01:27:54 +00001506{
njn810086f2002-11-14 12:42:47 +00001507 Supp* su;
sewardj8a7d4e42006-10-17 01:41:17 +00001508 Supp* su_prev;
1509
1510 /* stats gathering */
1511 em_supplist_searches++;
sewardjde4a1d02002-03-22 01:27:54 +00001512
sewardjde4a1d02002-03-22 01:27:54 +00001513 /* See if the error context matches any suppression. */
sewardj8a7d4e42006-10-17 01:41:17 +00001514 su_prev = NULL;
njn695c16e2005-03-27 03:40:28 +00001515 for (su = suppressions; su != NULL; su = su->next) {
sewardj8a7d4e42006-10-17 01:41:17 +00001516 em_supplist_cmps++;
1517 if (supp_matches_error(su, err) && supp_matches_callers(err, su)) {
1518 /* got a match. Move this entry to the head of the list
1519 in the hope of making future searches cheaper. */
1520 if (su_prev) {
1521 vg_assert(su_prev->next == su);
1522 su_prev->next = su->next;
1523 su->next = suppressions;
1524 suppressions = su;
1525 }
njn25e49d8e72002-09-23 09:36:25 +00001526 return su;
sewardjde4a1d02002-03-22 01:27:54 +00001527 }
sewardj8a7d4e42006-10-17 01:41:17 +00001528 su_prev = su;
sewardjde4a1d02002-03-22 01:27:54 +00001529 }
njn25e49d8e72002-09-23 09:36:25 +00001530 return NULL; /* no matches */
sewardjde4a1d02002-03-22 01:27:54 +00001531}
1532
sewardj8a7d4e42006-10-17 01:41:17 +00001533/* Show accumulated error-list and suppression-list search stats.
1534*/
1535void VG_(print_errormgr_stats) ( void )
1536{
sewardj738856f2009-07-15 14:48:32 +00001537 VG_(dmsg)(
1538 " errormgr: %'lu supplist searches, %'lu comparisons during search\n",
sewardj8a7d4e42006-10-17 01:41:17 +00001539 em_supplist_searches, em_supplist_cmps
1540 );
sewardj738856f2009-07-15 14:48:32 +00001541 VG_(dmsg)(
1542 " errormgr: %'lu errlist searches, %'lu comparisons during search\n",
sewardj8a7d4e42006-10-17 01:41:17 +00001543 em_errlist_searches, em_errlist_cmps
1544 );
1545}
1546
sewardjde4a1d02002-03-22 01:27:54 +00001547/*--------------------------------------------------------------------*/
njneb8896b2005-06-04 20:03:55 +00001548/*--- end ---*/
sewardjde4a1d02002-03-22 01:27:54 +00001549/*--------------------------------------------------------------------*/