You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
1
(36) |
2
(30) |
|
3
(17) |
4
(21) |
5
(18) |
6
(14) |
7
(23) |
8
(12) |
9
(11) |
|
10
(11) |
11
(12) |
12
(11) |
13
(12) |
14
(11) |
15
(11) |
16
(15) |
|
17
(12) |
18
(15) |
19
(15) |
20
(25) |
21
(26) |
22
(21) |
23
(18) |
|
24
(25) |
25
(28) |
26
(27) |
27
(32) |
28
(13) |
29
(12) |
30
(10) |
|
From: Nicholas N. <nj...@cs...> - 2005-04-19 23:52:14
|
On Tue, 19 Apr 2005, Benoit Peccatte wrote: > I'm developping a coverage tool for valgrind. How does it work? Is the output gcov-compatible? Does it give percentage coverage per file? I'm curious. > I've got almost all data I need but I can't find in which directory is a > source file for a given symbol. Does valgrind read this in formation ? I don't think so. N |
|
From: <sv...@va...> - 2005-04-19 23:06:24
|
Author: sewardj
Date: 2005-04-20 00:06:11 +0100 (Wed, 20 Apr 2005)
New Revision: 1131
Modified:
trunk/pub/libvex_ir.h
Log:
Update comment re PutI/GetI (comment-only change).
Modified: trunk/pub/libvex_ir.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/pub/libvex_ir.h 2005-04-07 17:31:27 UTC (rev 1130)
+++ trunk/pub/libvex_ir.h 2005-04-19 23:06:11 UTC (rev 1131)
@@ -383,7 +383,7 @@
Iop_MulHi16Ux4,
Iop_MulHi16Sx4,
=20
- /* AVERAGING: note: (arg1 + arg2 + 1) >> 1 */
+ /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
Iop_Avg8Ux8,
Iop_Avg16Ux4,
=20
@@ -500,7 +500,7 @@
Iop_MulHi16Ux8,
Iop_MulHi16Sx8,
=20
- /* AVERAGING: note: (arg1 + arg2 + 1) >> 1 */
+ /* AVERAGING: note: (arg1 + arg2 + 1) >>u 1 */
Iop_Avg8Ux16,
Iop_Avg16Ux8,
=20
@@ -562,21 +562,36 @@
=20
IRExpr_GetI (also IRStmt_PutI)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This carries two ints, which give the lowest and highest possible
- byte offsets that the GetI can possibly reference. For example, if
- the type is Ity_I32, and the Expr may have a value of M, M+4 or
- M+8, where M is a translation-time known constant, then the low and
- high limits are M and M+11 respectively.
+ These allow circular indexing into parts of the guest state, which
+ is essential for modelling situations where the identity of guest
+ registers is not known until run time. One example is the x87 FP
+ register stack.
=20
- PutI's limit values are interpreted identically.
+ The part of the guest state to be treated as a circular array is
+ described in an IRArray structure attached to the GetI/PutI.
+ IRArray holds the offset of the first element in the array, the
+ type of each element, and the number of elements.
=20
- The limit values are used by IR optimisers to establish
+ The array index is indicated rather indirectly, in a way which
+ makes optimisation easy: as the sum of variable part (the 'ix'
+ field) and a constant offset (the 'bias' field).
+
+ Since the indexing is circular, the actual array index to use
+ is computed as (ix + bias) % number-of-elements-in-the-array.
+
+ Here's an example. The description
+
+ (96:8xF64)[t39,-7]
+
+ describes an array of 8 F64-typed values, the guest-state-offset
+ of the first being 96. This array is being indexed at
+ (t39 - 7) % 8.
+
+ It is important to get the array size/type exactly correct since IR
+ optimisation looks closely at such info in order to establish
aliasing/non-aliasing between seperate GetI and PutI events, which
- could be used to do reordering of them, or suchlike things.
- Clearly it's critical to give the correct limit values -- this is
- something that can't be automatically checked (in general), and so
- the front-end writers must be very careful to tell the truth, since
- not doing so could lead to obscure IR optimisation bugs.
+ is used to establish when they can be reordered, etc. Putting
+ incorrect info in will lead to obscure IR optimisation bugs.
=20
IRExpr_CCall
~~~~~~~~~~~~
@@ -609,8 +624,7 @@
details about what the helper does (and you better be telling the
truth, otherwise any derived instrumentation will be wrong). Also
IRStmt_Dirty inhibits various IR optimisations and so can cause
- quite poor code to be generated. Try to avoid it. =20
-*/
+ quite poor code to be generated. Try to avoid it. */
=20
/* The possible kinds of expressions are as follows: */
typedef
|
|
From: Benoit P. <ben...@en...> - 2005-04-19 13:45:22
|
Hi, I'm developping a coverage tool for valgrind. I've got almost all=20 data I need but I can't find in which directory is a source file for a given symbol.=20 Does valgrind read this in formation ?=20 If yes, in which structure can I find it ? Thank you, Benoit |
|
From: Paul M. <pa...@sa...> - 2005-04-19 10:53:00
|
Craig Chaney writes: > This patch applies to Paul Mackerras' latest Valgrind PPC port > (http://ozlabs.org/~paulus/valgrind-2.4.0-ppc-050407.tar.bz2). Thanks for the patches. > (Please speak up if this list isn't an appropriate place to post patches > to Paul's port.) There are two things I am aiming at. The first is to have a solid, reliable PPC version of 2.4.0 available. The second is to get PPC support into the Valgrind subversion repository, with the aim of having Valgrind-3.0 support PPC. The parts of this patch that would be applicable to the subversion repository are the parts that move some tests to an x86 directory. > The patch contains some changes to help "make regtest" compile and run. > I had to make a handful of minor changes to the testcases to get them to > compile. Some of the testcases wouldn't compile due to x86 assembly; I > moved these to the x86 subdirectory. I also added some *.exp2 files for > cases where the valid output on PPC differed from the valid output on > x86. I would be interested to know why we seem to be getting file descriptors inherited from the parent on several of the tests. Does that happen on x86 also? Regards, Paul. |
|
From: <sv...@va...> - 2005-04-19 04:10:32
|
Author: njn
Date: 2005-04-19 05:10:25 +0100 (Tue, 19 Apr 2005)
New Revision: 3532
Added:
trunk/coregrind/errormgr.c
trunk/coregrind/pub_core_errormgr.h
trunk/include/pub_tool_errormgr.h
Removed:
trunk/coregrind/vg_errcontext.c
Modified:
trunk/coregrind/Makefile.am
trunk/coregrind/core.h
trunk/coregrind/vg_main.c
trunk/coregrind/vg_scheduler.c
trunk/coregrind/vg_signals.c
trunk/include/Makefile.am
trunk/include/tool.h.base
Log:
Renamed vg_errcontext.c as errormgr.c, and carved off the relevant parts =
of
core.h and tool.h into pub_core_errormgr.h and pub_tool_errormgr.h. All
just to improve general modularity.
Modified: trunk/coregrind/Makefile.am
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/Makefile.am 2005-04-16 14:58:34 UTC (rev 3531)
+++ trunk/coregrind/Makefile.am 2005-04-19 04:10:25 UTC (rev 3532)
@@ -27,6 +27,7 @@
noinst_HEADERS =3D \
core.h \
core_asm.h \
+ pub_core_errormgr.h \
pub_core_execontext.h \
pub_core_stacktrace.h \
ume.h \
@@ -51,6 +52,7 @@
valgrind_LDADD=3D
=20
stage2_SOURCES =3D \
+ errormgr.c \
execontext.c \
stacktrace.c \
ume.c \
@@ -58,7 +60,6 @@
vg_scheduler.c \
vg_default.c \
vg_demangle.c \
- vg_errcontext.c \
vg_hashtable.c \
vg_replace_malloc.c \
vg_main.c \
Modified: trunk/coregrind/core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/core.h 2005-04-16 14:58:34 UTC (rev 3531)
+++ trunk/coregrind/core.h 2005-04-19 04:10:25 UTC (rev 3532)
@@ -862,26 +862,6 @@
Int debugging_verbosity );
=20
/* ---------------------------------------------------------------------
- Exports of vg_errcontext.c.
- ------------------------------------------------------------------ */
-
-typedef
- enum {=20
- ThreadErr =3D -1, // Thread error
- MutexErr =3D -2, // Mutex error
- }
- CoreErrorKind;
-
-extern void VG_(load_suppressions) ( void );
-
-extern void VG_(show_all_errors) ( void );
-
-extern Bool VG_(is_action_requested) ( Char* action, Bool* clo );
-
-extern UInt VG_(get_n_errs_found) ( void );
-
-
-/* ---------------------------------------------------------------------
Exports of vg_procselfmaps.c
------------------------------------------------------------------ */
=20
Added: trunk/coregrind/errormgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/errormgr.c 2005-04-16 14:58:34 UTC (rev 3531)
+++ trunk/coregrind/errormgr.c 2005-04-19 04:10:25 UTC (rev 3532)
@@ -0,0 +1,1031 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Management of error messages. errormgr.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward=20
+ js...@ac...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#include "core.h"
+#include "pub_core_errormgr.h"
+#include "pub_core_execontext.h"
+#include "pub_core_stacktrace.h"
+
+/*------------------------------------------------------------*/
+/*--- Globals ---*/
+/*------------------------------------------------------------*/
+
+/* After this many different unsuppressed errors have been observed,
+ be more conservative about collecting new ones. */
+#define M_COLLECT_ERRORS_SLOWLY_AFTER 50
+
+/* After this many different unsuppressed errors have been observed,
+ stop collecting errors at all, and tell the user their program is
+ evidently a steaming pile of camel dung. */
+#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 300
+
+/* After this many total errors have been observed, stop collecting
+ errors at all. Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
+#define M_COLLECT_NO_ERRORS_AFTER_FOUND 30000
+
+/* The list of error contexts found, both suppressed and unsuppressed.
+ Initially empty, and grows as errors are detected. */
+static Error* errors =3D NULL;
+
+/* The list of suppression directives, as read from the specified
+ suppressions file. */
+static Supp* suppressions =3D NULL;
+
+/* Running count of unsuppressed errors detected. */
+static UInt n_errs_found =3D 0;
+
+/* Running count of suppressed errors detected. */
+static UInt n_errs_suppressed =3D 0;
+
+/* forwards ... */
+static Supp* is_suppressible_error ( Error* err );
+
+static ThreadId last_tid_printed =3D 1;
+
+/*------------------------------------------------------------*/
+/*--- Error type ---*/
+/*------------------------------------------------------------*/
+
+/* Note: it is imperative this doesn't overlap with (0..) at all, as too=
ls
+ * effectively extend it by defining their own enums in the (0..) range.=
*/
+
+/* Errors. Extensible (via the 'extra' field). Tools can use a normal
+ enum (with element values in the normal range (0..)) for `ekind'.=20
+ Functions for getting/setting the tool-relevant fields are in
+ include/tool.h.
+
+ When errors are found and recorded with VG_(maybe_record_error)(), al=
l
+ the tool must do is pass in the four parameters; core will
+ allocate/initialise the error record.
+*/
+struct _Error {
+ struct _Error* next;
+ // NULL if unsuppressed; or ptr to suppression record.
+ Supp* supp;
+ Int count;
+ ThreadId tid;
+
+ // The tool-specific part
+ ExeContext* where; // Initialised by core
+ ErrorKind ekind; // Used by ALL. Must be in the range (0..)
+ Addr addr; // Used frequently
+ Char* string; // Used frequently
+ void* extra; // For any tool-specific extras
+};
+
+ExeContext* VG_(get_error_where) ( Error* err )
+{
+ return err->where;
+}
+
+ErrorKind VG_(get_error_kind) ( Error* err )
+{
+ return err->ekind;
+}
+
+Addr VG_(get_error_address) ( Error* err )
+{
+ return err->addr;
+}
+
+Char* VG_(get_error_string) ( Error* err )
+{
+ return err->string;
+}
+
+void* VG_(get_error_extra) ( Error* err )
+{
+ return err->extra;
+}
+
+UInt VG_(get_n_errs_found)( void )
+{
+ return n_errs_found;
+}
+
+/*------------------------------------------------------------*/
+/*--- Suppression type ---*/
+/*------------------------------------------------------------*/
+
+/* Note: it is imperative this doesn't overlap with (0..) at all, as too=
ls
+ * effectively extend it by defining their own enums in the (0..) range.=
*/
+typedef
+ enum {
+ PThreadSupp =3D -1, /* Matches PThreadErr */
+ }
+ CoreSuppKind;
+
+/* Max number of callers for context in a suppression. */
+#define VG_MAX_SUPP_CALLERS 24
+
+/* For each caller specified for a suppression, record the nature of
+ the caller name. Not of interest to tools. */
+typedef
+ enum {=20
+ NoName, /* Error case */
+ ObjName, /* Name is of an shared object file. */
+ FunName /* Name is of a function. */
+ }
+ SuppLocTy;
+
+typedef
+ struct {
+ SuppLocTy ty;
+ Char* name;
+ }
+ SuppLoc;
+
+/* Suppressions. Tools can get/set tool-relevant parts with functions
+ declared in include/tool.h. Extensible via the 'extra' field.=20
+ Tools can use a normal enum (with element values in the normal range
+ (0..)) for `skind'. */
+struct _Supp {
+ struct _Supp* next;
+ Int count; // The number of times this error has been suppressed.
+ Char* sname; // The name by which the suppression is referred to.
+
+ // Length of 'callers'
+ Int n_callers;
+ // Array of callers, for matching stack traces. First one (name of f=
n
+ // where err occurs) is mandatory; rest are optional.
+ SuppLoc* callers;
+
+ /* The tool-specific part */
+ SuppKind skind; // What kind of suppression. Must use the range (0=
..).
+ Char* string; // String -- use is optional. NULL by default.
+ void* extra; // Anything else -- use is optional. NULL by defau=
lt.
+};
+
+SuppKind VG_(get_supp_kind) ( Supp* su )
+{
+ return su->skind;
+}
+
+Char* VG_(get_supp_string) ( Supp* su )
+{
+ return su->string;
+}
+
+void* VG_(get_supp_extra) ( Supp* su )
+{
+ return su->extra;
+}
+
+
+void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
+{
+ su->skind =3D skind;
+}
+
+void VG_(set_supp_string) ( Supp* su, Char* string )
+{
+ su->string =3D string;
+}
+
+void VG_(set_supp_extra) ( Supp* su, void* extra )
+{
+ su->extra =3D extra;
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Helper fns ---*/
+/*------------------------------------------------------------*/
+
+/* Compare error contexts, to detect duplicates. Note that if they
+ are otherwise the same, the faulting addrs and associated rwoffsets
+ are allowed to be different. */
+static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
+{
+ if (e1->ekind !=3D e2->ekind)=20
+ return False;
+ if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
+ return False;
+
+ switch (e1->ekind) {
+ // case ThreadErr:
+ // case MutexErr:
+ // vg_assert(VG_(needs).core_errors);
+ // return VG_(tm_error_equal)(res, e1, e2);
+ default:=20
+ if (VG_(needs).tool_errors)
+ return TL_(eq_Error)(res, e1, e2);
+ else {
+ VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_err=
ors\n"
+ "probably needs to be set.\n",
+ e1->ekind);
+ VG_(tool_panic)("unhandled error type");
+ }
+ }
+}
+
+static void pp_Error ( Error* err, Bool printCount )
+{
+ if (printCount)
+ VG_(message)(Vg_UserMsg, "Observed %d times:", err->count );
+ if (err->tid > 0 && err->tid !=3D last_tid_printed) {
+ VG_(message)(Vg_UserMsg, "Thread %d:", err->tid );
+ last_tid_printed =3D err->tid;
+ }
+
+ switch (err->ekind) {
+ // case ThreadErr:
+ // case MutexErr:
+ // vg_assert(VG_(needs).core_errors);
+ // VG_(tm_error_print)(err);
+ // break;
+ default:=20
+ if (VG_(needs).tool_errors)
+ TL_(pp_Error)( err );
+ else {
+ VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_er=
rors\n"
+ "probably needs to be set?\n",
+ err->ekind);
+ VG_(tool_panic)("unhandled error type");
+ }
+ }
+}
+
+/* Figure out if we want to perform a given action for this error, possi=
bly
+ by asking the user. */
+Bool VG_(is_action_requested) ( Char* action, Bool* clo )
+{
+ Char ch, ch2;
+ Int res;
+
+ if (*clo =3D=3D False)
+ return False;
+
+ VG_(message)(Vg_UserMsg, "");
+
+ again:
+ VG_(printf)(
+ "=3D=3D%d=3D=3D "
+ "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",=20
+ VG_(getpid)(), action
+ );
+
+ res =3D VG_(read)(VG_(clo_input_fd), &ch, 1);
+ if (res !=3D 1) goto ioerror;
+ /* res =3D=3D 1 */
+ if (ch =3D=3D '\n') return False;
+ if (ch !=3D 'N' && ch !=3D 'n' && ch !=3D 'Y' && ch !=3D 'y'=20
+ && ch !=3D 'C' && ch !=3D 'c') goto again;
+
+ res =3D VG_(read)(VG_(clo_input_fd), &ch2, 1);
+ if (res !=3D 1) goto ioerror;
+ if (ch2 !=3D '\n') goto again;
+
+ /* No, don't want to do action. */
+ if (ch =3D=3D 'n' || ch =3D=3D 'N') return False;
+ /* Yes, want to do action. */
+ if (ch =3D=3D 'y' || ch =3D=3D 'Y') return True;
+ /* No, don't want to do action, and don't ask again either. */
+ vg_assert(ch =3D=3D 'c' || ch =3D=3D 'C');
+
+ ioerror:
+ *clo =3D False;
+ return False;
+}
+
+
+/* Construct an error */
+static __inline__
+void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a=
,
+ Char* s, void* extra, ExeContext* where )
+{
+ tl_assert(tid < VG_N_THREADS);
+
+ /* Core-only parts */
+ err->next =3D NULL;
+ err->supp =3D NULL;
+ err->count =3D 1;
+ err->tid =3D tid;
+ if (NULL =3D=3D where)
+ err->where =3D VG_(record_ExeContext)( tid );
+ else
+ err->where =3D where;
+
+ /* Tool-relevant parts */
+ err->ekind =3D ekind;
+ err->addr =3D a;
+ err->extra =3D extra;
+ err->string =3D s;
+
+ /* sanity... */
+ vg_assert( tid < VG_N_THREADS );
+}
+
+static void printSuppForIp(UInt n, Addr ip)
+{
+ static UChar buf[VG_ERRTXT_LEN];
+
+ if ( VG_(get_fnname_nodemangle) (ip, buf, VG_ERRTXT_LEN) ) {
+ VG_(printf)(" fun:%s\n", buf);
+ } else if ( VG_(get_objname)(ip, buf+7, VG_ERRTXT_LEN-7) ) {
+ VG_(printf)(" obj:%s\n", buf);
+ } else {
+ VG_(printf)(" ???:??? "
+ "# unknown, suppression will not work, sorry\n");
+ }
+}
+
+static void gen_suppression(Error* err)
+{
+ ExeContext* ec =3D VG_(get_error_where)(err);
+ Int stop_at =3D VG_(clo_backtrace_size);
+
+ /* At most VG_MAX_SUPP_CALLERS names */
+ if (stop_at > VG_MAX_SUPP_CALLERS) stop_at =3D VG_MAX_SUPP_CALLERS;
+ vg_assert(stop_at > 0);
+
+ VG_(printf)("{\n");
+ VG_(printf)(" <insert a suppression name here>\n");
+
+ if (ThreadErr =3D=3D err->ekind || MutexErr =3D=3D err->ekind) {
+ VG_(printf)(" core:PThread\n");
+
+ } else {
+ Char* name =3D TL_(get_error_name)(err);
+ if (NULL =3D=3D name) {
+ VG_(message)(Vg_UserMsg,=20
+ "(tool does not allow error to be suppressed)");
+ return;
+ }
+ VG_(printf)(" %s:%s\n", VG_(details).name, name);
+ TL_(print_extra_suppression_info)(err);
+ }
+
+ // Print stack trace elements
+ VG_(apply_StackTrace)(printSuppForIp, VG_(extract_StackTrace)(ec), st=
op_at);
+
+ VG_(printf)("}\n");
+}
+
+static=20
+void do_actions_on_error(Error* err, Bool allow_db_attach)
+{
+ Bool still_noisy =3D True;
+
+ /* Perhaps we want a debugger attach at this point? */
+ if (allow_db_attach &&
+ VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_atta=
ch) ))
+ { =20
+ VG_(printf)("starting debugger\n");
+ VG_(start_debugger)( err->tid );
+ } =20
+ /* Or maybe we want to generate the error's suppression? */
+ if (VG_(clo_gen_suppressions) =3D=3D 2
+ || (VG_(clo_gen_suppressions) =3D=3D 1
+ && VG_(is_action_requested)( "Print suppression", &still_nois=
y ))
+ ) {
+ gen_suppression(err);
+ if (VG_(clo_gen_suppressions) =3D=3D 1 && !still_noisy)
+ VG_(clo_gen_suppressions) =3D 0;
+ }
+}
+
+/* Shared between VG_(maybe_record_error)() and VG_(unique_error)(),
+ just for pretty printing purposes. */
+static Bool is_first_shown_context =3D True;
+
+/* Top-level entry point to the error management subsystem.
+ All detected errors are notified here; this routine decides if/when t=
he
+ user should see the error. */
+void VG_(maybe_record_error) ( ThreadId tid,=20
+ ErrorKind ekind, Addr a, Char* s, void* e=
xtra )
+{
+ Error err;
+ Error* p;
+ Error* p_prev;
+ UInt extra_size;
+ VgRes exe_res =3D Vg_MedRes;
+ static Bool stopping_message =3D False;
+ static Bool slowdown_message =3D False;
+ static Int n_errs_shown =3D 0;
+
+ /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
+ been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
+ have been found, just refuse to collect any more. This stops
+ the burden of the error-management system becoming excessive in
+ extremely buggy programs, although it does make it pretty
+ pointless to continue the Valgrind run after this point. */
+ if (VG_(clo_error_limit)=20
+ && (n_errs_shown >=3D M_COLLECT_NO_ERRORS_AFTER_SHOWN
+ || n_errs_found >=3D M_COLLECT_NO_ERRORS_AFTER_FOUND)) {
+ if (!stopping_message) {
+ VG_(message)(Vg_UserMsg, "");
+
+ if (n_errs_shown >=3D M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
+ VG_(message)(Vg_UserMsg,=20
+ "More than %d different errors detected. "
+ "I'm not reporting any more.",
+ M_COLLECT_NO_ERRORS_AFTER_SHOWN );
+ } else {
+ VG_(message)(Vg_UserMsg,=20
+ "More than %d total errors detected. "
+ "I'm not reporting any more.",
+ M_COLLECT_NO_ERRORS_AFTER_FOUND );
+ }
+
+ VG_(message)(Vg_UserMsg,=20
+ "Final error counts will be inaccurate. Go fix your program=
!");
+ VG_(message)(Vg_UserMsg,=20
+ "Rerun with --error-limit=3Dno to disable this cutoff. Note=
");
+ VG_(message)(Vg_UserMsg,=20
+ "that errors may occur in your program without prior warning=
from");
+ VG_(message)(Vg_UserMsg,=20
+ "Valgrind, because errors are no longer being displayed.");
+ VG_(message)(Vg_UserMsg, "");
+ stopping_message =3D True;
+ }
+ return;
+ }
+
+ /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
+ been found, be much more conservative about collecting new
+ ones. */
+ if (n_errs_shown >=3D M_COLLECT_ERRORS_SLOWLY_AFTER) {
+ exe_res =3D Vg_LowRes;
+ if (!slowdown_message) {
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg,=20
+ "More than %d errors detected. Subsequent errors",
+ M_COLLECT_ERRORS_SLOWLY_AFTER);
+ VG_(message)(Vg_UserMsg,=20
+ "will still be recorded, but in less detail than before.");
+ slowdown_message =3D True;
+ }
+ }
+
+ /* Build ourselves the error */
+ construct_error ( &err, tid, ekind, a, s, extra, NULL );
+
+ /* First, see if we've got an error record matching this one. */
+ p =3D errors;
+ p_prev =3D NULL;
+ while (p !=3D NULL) {
+ if (eq_Error(exe_res, p, &err)) {
+ /* Found it. */
+ p->count++;
+ if (p->supp !=3D NULL) {
+ /* Deal correctly with suppressed errors. */
+ p->supp->count++;
+ n_errs_suppressed++; =20
+ } else {
+ n_errs_found++;
+ }
+
+ /* Move p to the front of the list so that future searches
+ for it are faster. */
+ if (p_prev !=3D NULL) {
+ vg_assert(p_prev->next =3D=3D p);
+ p_prev->next =3D p->next;
+ p->next =3D errors;
+ errors =3D p;
+ }
+
+ return;
+ }
+ p_prev =3D p;
+ p =3D p->next;
+ }
+
+ /* Didn't see it. Copy and add. */
+
+ /* OK, we're really going to collect it. The context is on the stack=
and
+ will disappear shortly, so we must copy it. First do the main
+ (non-`extra') part.
+ =20
+ Then TL_(update_extra) can update the `extra' part. This is for w=
hen
+ there are more details to fill in which take time to work out but
+ don't affect our earlier decision to include the error -- by
+ postponing those details until now, we avoid the extra work in the
+ case where we ignore the error. Ugly.
+
+ Then, if there is an `extra' part, copy it too, using the size tha=
t
+ TL_(update_extra) returned. Also allow for people using the void*
+ extra field for a scalar value like an integer.
+ */
+
+ /* copy main part */
+ p =3D VG_(arena_malloc)(VG_AR_ERRORS, sizeof(Error));
+ *p =3D err;
+
+ /* update `extra' */
+ switch (ekind) {
+ // case ThreadErr:
+ // case MutexErr:
+ // vg_assert(VG_(needs).core_errors);
+ // extra_size =3D VG_(tm_error_update_extra)(p);
+ // break;
+ default:
+ vg_assert(VG_(needs).tool_errors);
+ extra_size =3D TL_(update_extra)(p);
+ break;
+ }
+
+ /* copy block pointed to by `extra', if there is one */
+ if (NULL !=3D p->extra && 0 !=3D extra_size) {=20
+ void* new_extra =3D VG_(malloc)(extra_size);
+ VG_(memcpy)(new_extra, p->extra, extra_size);
+ p->extra =3D new_extra;
+ }
+
+ p->next =3D errors;
+ p->supp =3D is_suppressible_error(&err);
+ errors =3D p;
+ if (p->supp =3D=3D NULL) {
+ n_errs_found++;
+ if (!is_first_shown_context)
+ VG_(message)(Vg_UserMsg, "");
+ pp_Error(p, False);
+ is_first_shown_context =3D False;
+ n_errs_shown++;
+ do_actions_on_error(p, /*allow_db_attach*/True);
+ } else {
+ n_errs_suppressed++;
+ p->supp->count++;
+ }
+}
+
+/* Second top-level entry point to the error management subsystem, for
+ errors that the tool wants to report immediately, eg. because they're
+ guaranteed to only happen once. This avoids all the recording and
+ comparing stuff. But they can be suppressed; returns True if it is
+ suppressed. Bool `print_error' dictates whether to print the error.=20
+ Bool `count_error' dictates whether to count the error in n_errs_foun=
d.
+*/
+Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
+ void* extra, ExeContext* where, Bool print_erro=
r,
+ Bool allow_db_attach, Bool count_error )
+{
+ Error err;
+
+ /* Build ourselves the error */
+ construct_error ( &err, tid, ekind, a, s, extra, where );
+
+ /* Unless it's suppressed, we're going to show it. Don't need to mak=
e
+ a copy, because it's only temporary anyway.
+
+ Then update the `extra' part with TL_(update_extra), because that =
can
+ have an affect on whether it's suppressed. Ignore the size return
+ value of TL_(update_extra), because we're not copying `extra'. */
+ (void)TL_(update_extra)(&err);
+
+ if (NULL =3D=3D is_suppressible_error(&err)) {
+ if (count_error)
+ n_errs_found++;
+
+ if (print_error) {
+ if (!is_first_shown_context)
+ VG_(message)(Vg_UserMsg, "");
+ pp_Error(&err, False);
+ is_first_shown_context =3D False;
+ }
+ do_actions_on_error(&err, allow_db_attach);
+
+ return False;
+
+ } else {
+ n_errs_suppressed++;
+ return True;
+ }
+}
+
+
+/*------------------------------------------------------------*/
+/*--- Exported fns ---*/
+/*------------------------------------------------------------*/
+
+/* This is called not from generated code but from the scheduler */
+void VG_(show_all_errors) ( void )
+{
+ Int i, n_min;
+ Int n_err_contexts, n_supp_contexts;
+ Error *p, *p_min;
+ Supp *su;
+ Bool any_supp;
+
+ if (VG_(clo_verbosity) =3D=3D 0)
+ return;
+
+ n_err_contexts =3D 0;
+ for (p =3D errors; p !=3D NULL; p =3D p->next) {
+ if (p->supp =3D=3D NULL)
+ n_err_contexts++;
+ }
+
+ n_supp_contexts =3D 0;
+ for (su =3D suppressions; su !=3D NULL; su =3D su->next) {
+ if (su->count > 0)
+ n_supp_contexts++;
+ }
+ VG_(message)(Vg_UserMsg,
+ "ERROR SUMMARY: "
+ "%d errors from %d contexts (suppressed: %d from %d)",
+ n_errs_found, n_err_contexts,=20
+ n_errs_suppressed, n_supp_contexts );
+
+ if (VG_(clo_verbosity) <=3D 1)
+ return;
+
+ /* Print the contexts in order of increasing error count. */
+ for (i =3D 0; i < n_err_contexts; i++) {
+ n_min =3D (1 << 30) - 1;
+ p_min =3D NULL;
+ for (p =3D errors; p !=3D NULL; p =3D p->next) {
+ if (p->supp !=3D NULL) continue;
+ if (p->count < n_min) {
+ n_min =3D p->count;
+ p_min =3D p;
+ }
+ }
+ if (p_min =3D=3D NULL) VG_(tool_panic)("show_all_errors()");
+
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg, "%d errors in context %d of %d:",
+ p_min->count,
+ i+1, n_err_contexts);
+ pp_Error( p_min, False );
+
+ if ((i+1 =3D=3D VG_(clo_dump_error))) {
+ StackTrace ips =3D VG_(extract_StackTrace)(p_min->where);
+ VG_(translate) ( 0 /* dummy ThreadId; irrelevant due to debuggi=
ng*/,
+ ips[0], /*debugging*/True, 0xFE/*verbosity*/);
+ }
+
+ p_min->count =3D 1 << 30;
+ }=20
+
+ if (n_supp_contexts > 0)=20
+ VG_(message)(Vg_DebugMsg, "");
+ any_supp =3D False;
+ for (su =3D suppressions; su !=3D NULL; su =3D su->next) {
+ if (su->count > 0) {
+ any_supp =3D True;
+ VG_(message)(Vg_DebugMsg, "supp: %4d %s", su->count, su->sname)=
;
+ }
+ }
+
+ if (n_err_contexts > 0) {
+ if (any_supp)=20
+ VG_(message)(Vg_UserMsg, "");
+ VG_(message)(Vg_UserMsg,
+ "IN SUMMARY: "
+ "%d errors from %d contexts (suppressed: %d from %d)"=
,
+ n_errs_found, n_err_contexts, n_errs_suppressed,
+ n_supp_contexts );
+ VG_(message)(Vg_UserMsg, "");
+ }
+}
+
+/*------------------------------------------------------------*/
+/*--- Standard suppressions ---*/
+/*------------------------------------------------------------*/
+
+/* Get a non-blank, non-comment line of at most nBuf chars from fd.
+ Skips leading spaces on the line. Return True if EOF was hit instead.=
=20
+*/
+Bool VG_(get_line) ( Int fd, Char* buf, Int nBuf )
+{
+ Char ch;
+ Int n, i;
+ while (True) {
+ /* First, read until a non-blank char appears. */
+ while (True) {
+ n =3D VG_(read)(fd, &ch, 1);
+ if (n =3D=3D 1 && !VG_(isspace)(ch)) break;
+ if (n =3D=3D 0) return True;
+ }
+
+ /* Now, read the line into buf. */
+ i =3D 0;
+ buf[i++] =3D ch; buf[i] =3D 0;
+ while (True) {
+ n =3D VG_(read)(fd, &ch, 1);
+ if (n =3D=3D 0) return False; /* the next call will return True=
*/
+ if (ch =3D=3D '\n') break;
+ if (i > 0 && i =3D=3D nBuf-1) i--;
+ buf[i++] =3D ch; buf[i] =3D 0;
+ }
+ while (i > 1 && VG_(isspace)(buf[i-1])) {=20
+ i--; buf[i] =3D 0;=20
+ };
+
+ /* VG_(printf)("The line is `%s'\n", buf); */
+ /* Ok, we have a line. If a non-comment line, return.
+ If a comment line, start all over again. */
+ if (buf[0] !=3D '#') return False;
+ }
+}
+
+
+/* *p_caller contains the raw name of a caller, supposedly either
+ fun:some_function_name or
+ obj:some_object_name.
+ Set *p_ty accordingly and advance *p_caller over the descriptor
+ (fun: or obj:) part.
+ Returns False if failed.
+*/
+static Bool setLocationTy ( SuppLoc* p )
+{
+ if (VG_(strncmp)(p->name, "fun:", 4) =3D=3D 0) {
+ p->name +=3D 4;
+ p->ty =3D FunName;
+ return True;
+ }
+ if (VG_(strncmp)(p->name, "obj:", 4) =3D=3D 0) {
+ p->name +=3D 4;
+ p->ty =3D ObjName;
+ return True;
+ }
+ VG_(printf)("location should start with fun: or obj:\n");
+ return False;
+}
+
+
+/* Look for "tool" in a string like "tool1,tool2,tool3" */
+static __inline__
+Bool tool_name_present(Char *name, Char *names)
+{
+ Bool found;
+ Char *s =3D NULL; /* Shut gcc up */
+ Int len =3D VG_(strlen)(name);
+
+ found =3D (NULL !=3D (s =3D VG_(strstr)(names, name)) &&
+ (s =3D=3D names || *(s-1) =3D=3D ',') &&
+ (*(s+len) =3D=3D ',' || *(s+len) =3D=3D '\0')
+ );
+
+ return found;
+}
+
+/* Read suppressions from the file specified in VG_(clo_suppressions)
+ and place them in the suppressions list. If there's any difficulty
+ doing this, just give up -- there's no point in trying to recover. =20
+*/
+static void load_one_suppressions_file ( Char* filename )
+{
+# define N_BUF 200
+ Int fd, i;
+ Bool eof;
+ Char buf[N_BUF+1];
+ Char* tool_names;
+ Char* supp_name;
+ Char* err_str =3D NULL;
+ SuppLoc tmp_callers[VG_MAX_SUPP_CALLERS];
+
+ fd =3D VG_(open)( filename, VKI_O_RDONLY, 0 );
+ if (fd < 0) {
+ VG_(message)(Vg_UserMsg, "FATAL: can't open suppressions file `%s'=
",=20
+ filename );
+ VG_(exit)(1);
+ }
+
+#define BOMB(S) { err_str =3D S; goto syntax_error; }
+
+ while (True) {
+ /* Assign and initialise the two suppression halves (core and tool=
) */
+ Supp* supp;
+ supp =3D VG_(arena_malloc)(VG_AR_CORE, sizeof(Supp));
+ supp->count =3D 0;
+
+ // Initialise temporary reading-in buffer.
+ for (i =3D 0; i < VG_MAX_SUPP_CALLERS; i++) {
+ tmp_callers[i].ty =3D NoName;
+ tmp_callers[i].name =3D NULL;
+ }
+
+ supp->string =3D supp->extra =3D NULL;
+
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+ if (eof) break;
+
+ if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
+ =20
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+
+ if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
+
+ supp->sname =3D VG_(arena_strdup)(VG_AR_CORE, buf);
+
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+
+ if (eof) BOMB("unexpected end-of-file");
+
+ /* Check it has the "tool1,tool2,...:supp" form (look for ':') */
+ i =3D 0;
+ while (True) {
+ if (buf[i] =3D=3D ':') break;
+ if (buf[i] =3D=3D '\0') BOMB("malformed 'tool1,tool2,...:supp' =
line");
+ i++;
+ }
+ buf[i] =3D '\0'; /* Replace ':', splitting into two strings =
*/
+
+ tool_names =3D & buf[0];
+ supp_name =3D & buf[i+1];
+
+ if (VG_(needs).core_errors && tool_name_present("core", tool_names=
))
+ {
+ // A core suppression
+ if (VG_STREQ(supp_name, "PThread"))
+ supp->skind =3D PThreadSupp;
+ else
+ BOMB("unknown core suppression type");
+ }
+ else if (VG_(needs).tool_errors &&=20
+ tool_name_present(VG_(details).name, tool_names))
+ {
+ // A tool suppression
+ if (TL_(recognised_suppression)(supp_name, supp)) {
+ /* Do nothing, function fills in supp->skind */
+ } else {
+ BOMB("unknown tool suppression type");
+ }
+ }
+ else {
+ // Ignore rest of suppression
+ while (True) {
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+ if (eof) BOMB("unexpected end-of-file");
+ if (VG_STREQ(buf, "}"))
+ break;
+ }
+ continue;
+ }
+
+ if (VG_(needs).tool_errors &&=20
+ !TL_(read_extra_suppression_info)(fd, buf, N_BUF, supp))
+ {
+ BOMB("bad or missing extra suppression info");
+ }
+
+ i =3D 0;
+ while (True) {
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+ if (eof)
+ BOMB("unexpected end-of-file");
+ if (VG_STREQ(buf, "}")) {
+ if (i > 0) {
+ break;
+ } else {
+ BOMB("missing stack trace");
+ }
+ }
+ if (i =3D=3D VG_MAX_SUPP_CALLERS)
+ BOMB("too many callers in stack trace");
+ if (i > 0 && i >=3D VG_(clo_backtrace_size))=20
+ break;
+ tmp_callers[i].name =3D VG_(arena_strdup)(VG_AR_CORE, buf);
+ if (!setLocationTy(&(tmp_callers[i])))
+ BOMB("location should start with 'fun:' or 'obj:'");
+ i++;
+ }
+
+ // If the num callers is >=3D VG_(clo_backtrace_size), ignore any =
extra
+ // lines and grab the '}'.
+ if (!VG_STREQ(buf, "}")) {
+ do {
+ eof =3D VG_(get_line) ( fd, buf, N_BUF );
+ } while (!eof && !VG_STREQ(buf, "}"));
+ }
+
+ // Copy tmp_callers[] into supp->callers[]
+ supp->n_callers =3D i;
+ supp->callers =3D VG_(arena_malloc)(VG_AR_CORE, i*sizeof(SuppLoc))=
;
+ for (i =3D 0; i < supp->n_callers; i++) {
+ supp->callers[i] =3D tmp_callers[i];
+ }
+
+ supp->next =3D suppressions;
+ suppressions =3D supp;
+ }
+ VG_(close)(fd);
+ return;
+
+ syntax_error:
+ VG_(message)(Vg_UserMsg,=20
+ "FATAL: in suppressions file `%s': %s", filename, err_st=
r );
+ =20
+ VG_(close)(fd);
+ VG_(message)(Vg_UserMsg, "exiting now.");
+ VG_(exit)(1);
+
+# undef BOMB
+# undef N_BUF =20
+}
+
+
+void VG_(load_suppressions) ( void )
+{
+ Int i;
+ suppressions =3D NULL;
+ for (i =3D 0; i < VG_(clo_n_suppressions); i++) {
+ if (VG_(clo_verbosity) > 1) {
+ VG_(message)(Vg_DebugMsg, "Reading suppressions file: %s",=20
+ VG_(clo_suppressions)[i] );
+ }
+ load_one_suppressions_file( VG_(clo_suppressions)[i] );
+ }
+}
+
+static
+Bool supp_matches_error(Supp* su, Error* err)
+{
+ switch (su->skind) {
+ case PThreadSupp:
+ return (err->ekind =3D=3D ThreadErr || err->ekind =3D=3D MutexE=
rr);
+ default:
+ if (VG_(needs).tool_errors) {
+ return TL_(error_matches_suppression)(err, su);
+ } else {
+ VG_(printf)(
+ "\nUnhandled suppression type: %u. VG_(needs).tool_error=
s\n"
+ "probably needs to be set.\n",
+ err->ekind);
+ VG_(tool_panic)("unhandled suppression type");
+ }
+ }
+}
+
+static
+Bool supp_matches_callers(Error* err, Supp* su)
+{
+ Int i;
+ Char caller_name[VG_ERRTXT_LEN];
+ StackTrace ips =3D VG_(extract_StackTrace)(err->where);
+
+ for (i =3D 0; i < su->n_callers; i++) {
+ Addr a =3D ips[i];
+ vg_assert(su->callers[i].name !=3D NULL);
+ switch (su->callers[i].ty) {
+ case ObjName:=20
+ if (!VG_(get_objname)(a, caller_name, VG_ERRTXT_LEN))
+ return False;
+ break;=20
+
+ case FunName:=20
+ // Nb: mangled names used in suppressions
+ if (!VG_(get_fnname_nodemangle)(a, caller_name, VG_ERRTXT_LE=
N))
+ return False;
+ break;
+ default: VG_(tool_panic)("supp_matches_callers");
+ }
+ if (!VG_(string_match)(su->callers[i].name, caller_name))
+ return False;
+ }
+
+ /* If we reach here, it's a match */
+ return True;
+}
+
+/* Does an error context match a suppression? ie is this a suppressible
+ error? If so, return a pointer to the Supp record, otherwise NULL.
+ Tries to minimise the number of symbol searches since they are expens=
ive. =20
+*/
+static Supp* is_suppressible_error ( Error* err )
+{
+ Supp* su;
+
+ /* See if the error context matches any suppression. */
+ for (su =3D suppressions; su !=3D NULL; su =3D su->next) {
+ if (supp_matches_error(su, err) &&
+ supp_matches_callers(err, su))
+ {
+ return su;
+ }
+ }
+ return NULL; /* no matches */
+}
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
Added: trunk/coregrind/pub_core_errormgr.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/pub_core_errormgr.h 2005-04-16 14:58:34 UTC (rev 3531=
)
+++ trunk/coregrind/pub_core_errormgr.h 2005-04-19 04:10:25 UTC (rev 3532=
)
@@ -0,0 +1,64 @@
+/*--------------------------------------------------------------------*/
+/*--- ErrorMgr: management of errors and suppressions. ---*/
+/*--- pub_core_errormgr.h ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Julian Seward
+ js...@ac...
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The GNU General Public License is contained in the file COPYING.
+*/
+
+#ifndef __PUB_CORE_ERRORMGR_H
+#define __PUB_CORE_ERRORMGR_H
+
+//--------------------------------------------------------------------
+// PURPOSE: This module manages errors recording and printing,=20
+// which includes suppression reading and writing.
+//--------------------------------------------------------------------
+
+#include "pub_tool_errormgr.h"
+
+//#include "pub_core_stacktrace.h"
+
+// XXX: should this be in pthreadmodel.c?
+// These must be negative, so as to not overlap with tool error kinds.
+typedef
+ enum {=20
+ ThreadErr =3D -1, // Thread error
+ MutexErr =3D -2, // Mutex error
+ }
+ CoreErrorKind;
+
+extern void VG_(load_suppressions) ( void );
+
+extern void VG_(show_all_errors) ( void );
+
+extern Bool VG_(is_action_requested) ( Char* action, Bool* clo );
+
+extern UInt VG_(get_n_errs_found) ( void );
+
+#endif // __PUB_CORE_ERRORMGR_H
+
+/*--------------------------------------------------------------------*/
+/*--- end ---*/
+/*--------------------------------------------------------------------*/
Deleted: trunk/coregrind/vg_errcontext.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/coregrind/vg_errcontext.c 2005-04-16 14:58:34 UTC (rev 3531)
+++ trunk/coregrind/vg_errcontext.c 2005-04-19 04:10:25 UTC (rev 3532)
@@ -1,1030 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Management of error messages. vg_errcontext.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Julian Seward=20
- js...@ac...
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307, USA.
-
- The GNU General Public License is contained in the file COPYING.
-*/
-
-#include "core.h"
-#include "pub_core_execontext.h"
-
-/*------------------------------------------------------------*/
-/*--- Globals ---*/
-/*------------------------------------------------------------*/
-
-/* After this many different unsuppressed errors have been observed,
- be more conservative about collecting new ones. */
-#define M_COLLECT_ERRORS_SLOWLY_AFTER 50
-
-/* After this many different unsuppressed errors have been observed,
- stop collecting errors at all, and tell the user their program is
- evidently a steaming pile of camel dung. */
-#define M_COLLECT_NO_ERRORS_AFTER_SHOWN 300
-
-/* After this many total errors have been observed, stop collecting
- errors at all. Counterpart to M_COLLECT_NO_ERRORS_AFTER_SHOWN. */
-#define M_COLLECT_NO_ERRORS_AFTER_FOUND 30000
-
-/* The list of error contexts found, both suppressed and unsuppressed.
- Initially empty, and grows as errors are detected. */
-static Error* errors =3D NULL;
-
-/* The list of suppression directives, as read from the specified
- suppressions file. */
-static Supp* suppressions =3D NULL;
-
-/* Running count of unsuppressed errors detected. */
-static UInt n_errs_found =3D 0;
-
-/* Running count of suppressed errors detected. */
-static UInt n_errs_suppressed =3D 0;
-
-/* forwards ... */
-static Supp* is_suppressible_error ( Error* err );
-
-static ThreadId last_tid_printed =3D 1;
-
-/*------------------------------------------------------------*/
-/*--- Error type ---*/
-/*------------------------------------------------------------*/
-
-/* Note: it is imperative this doesn't overlap with (0..) at all, as too=
ls
- * effectively extend it by defining their own enums in the (0..) range.=
*/
-
-/* Errors. Extensible (via the 'extra' field). Tools can use a normal
- enum (with element values in the normal range (0..)) for `ekind'.=20
- Functions for getting/setting the tool-relevant fields are in
- include/tool.h.
-
- When errors are found and recorded with VG_(maybe_record_error)(), al=
l
- the tool must do is pass in the four parameters; core will
- allocate/initialise the error record.
-*/
-struct _Error {
- struct _Error* next;
- // NULL if unsuppressed; or ptr to suppression record.
- Supp* supp;
- Int count;
- ThreadId tid;
-
- // The tool-specific part
- ExeContext* where; // Initialised by core
- Int ekind; // Used by ALL. Must be in the range (0..)
- Addr addr; // Used frequently
- Char* string; // Used frequently
- void* extra; // For any tool-specific extras
-};
-
-ExeContext* VG_(get_error_where) ( Error* err )
-{
- return err->where;
-}
-
-ErrorKind VG_(get_error_kind) ( Error* err )
-{
- return err->ekind;
-}
-
-Addr VG_(get_error_address) ( Error* err )
-{
- return err->addr;
-}
-
-Char* VG_(get_error_string) ( Error* err )
-{
- return err->string;
-}
-
-void* VG_(get_error_extra) ( Error* err )
-{
- return err->extra;
-}
-
-UInt VG_(get_n_errs_found)( void )
-{
- return n_errs_found;
-}
-
-/*------------------------------------------------------------*/
-/*--- Suppression type ---*/
-/*------------------------------------------------------------*/
-
-/* Note: it is imperative this doesn't overlap with (0..) at all, as too=
ls
- * effectively extend it by defining their own enums in the (0..) range.=
*/
-typedef
- enum {
- PThreadSupp =3D -1, /* Matches PThreadErr */
- }
- CoreSuppKind;
-
-/* Max number of callers for context in a suppression. */
-#define VG_MAX_SUPP_CALLERS 24
-
-/* For each caller specified for a suppression, record the nature of
- the caller name. Not of interest to tools. */
-typedef
- enum {=20
- NoName, /* Error case */
- ObjName, /* Name is of an shared object file. */
- FunName /* Name is of a function. */
- }
- SuppLocTy;
-
-typedef
- struct {
- SuppLocTy ty;
- Char* name;
- }
- SuppLoc;
-
-/* Suppressions. Tools can get/set tool-relevant parts with functions
- declared in include/tool.h. Extensible via the 'extra' field.=20
- Tools can use a normal enum (with element values in the normal range
- (0..)) for `skind'. */
-struct _Supp {
- struct _Supp* next;
- Int count; // The number of times this error has been suppressed.
- Char* sname; // The name by which the suppression is referred to.
-
- // Length of 'callers'
- Int n_callers;
- // Array of callers, for matching stack traces. First one (name of f=
n
- // where err occurs) is mandatory; rest are optional.
- SuppLoc* callers;
-
- /* The tool-specific part */
- SuppKind skind; // What kind of suppression. Must use the range (0=
..).
- Char* string; // String -- use is optional. NULL by default.
- void* extra; // Anything else -- use is optional. NULL by defau=
lt.
-};
-
-SuppKind VG_(get_supp_kind) ( Supp* su )
-{
- return su->skind;
-}
-
-Char* VG_(get_supp_string) ( Supp* su )
-{
- return su->string;
-}
-
-void* VG_(get_supp_extra) ( Supp* su )
-{
- return su->extra;
-}
-
-
-void VG_(set_supp_kind) ( Supp* su, SuppKind skind )
-{
- su->skind =3D skind;
-}
-
-void VG_(set_supp_string) ( Supp* su, Char* string )
-{
- su->string =3D string;
-}
-
-void VG_(set_supp_extra) ( Supp* su, void* extra )
-{
- su->extra =3D extra;
-}
-
-
-/*------------------------------------------------------------*/
-/*--- Helper fns ---*/
-/*------------------------------------------------------------*/
-
-/* Compare error contexts, to detect duplicates. Note that if they
- are otherwise the same, the faulting addrs and associated rwoffsets
- are allowed to be different. */
-static Bool eq_Error ( VgRes res, Error* e1, Error* e2 )
-{
- if (e1->ekind !=3D e2->ekind)=20
- return False;
- if (!VG_(eq_ExeContext)(res, e1->where, e2->where))
- return False;
-
- switch (e1->ekind) {
- // case ThreadErr:
- // case MutexErr:
- // vg_assert(VG_(needs).core_errors);
- // return VG_(tm_error_equal)(res, e1, e2);
- default:=20
- if (VG_(needs).tool_errors)
- return TL_(eq_Error)(res, e1, e2);
- else {
- VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_err=
ors\n"
- "probably needs to be set.\n",
- e1->ekind);
- VG_(tool_panic)("unhandled error type");
- }
- }
-}
-
-static void pp_Error ( Error* err, Bool printCount )
-{
- if (printCount)
- VG_(message)(Vg_UserMsg, "Observed %d times:", err->count );
- if (err->tid > 0 && err->tid !=3D last_tid_printed) {
- VG_(message)(Vg_UserMsg, "Thread %d:", err->tid );
- last_tid_printed =3D err->tid;
- }
-
- switch (err->ekind) {
- // case ThreadErr:
- // case MutexErr:
- // vg_assert(VG_(needs).core_errors);
- // VG_(tm_error_print)(err);
- // break;
- default:=20
- if (VG_(needs).tool_errors)
- TL_(pp_Error)( err );
- else {
- VG_(printf)("\nUnhandled error type: %u. VG_(needs).tool_er=
rors\n"
- "probably needs to be set?\n",
- err->ekind);
- VG_(tool_panic)("unhandled error type");
- }
- }
-}
-
-/* Figure out if we want to perform a given action for this error, possi=
bly
- by asking the user. */
-Bool VG_(is_action_requested) ( Char* action, Bool* clo )
-{
- Char ch, ch2;
- Int res;
-
- if (*clo =3D=3D False)
- return False;
-
- VG_(message)(Vg_UserMsg, "");
-
- again:
- VG_(printf)(
- "=3D=3D%d=3D=3D "
- "---- %s ? --- [Return/N/n/Y/y/C/c] ---- ",=20
- VG_(getpid)(), action
- );
-
- res =3D VG_(read)(VG_(clo_input_fd), &ch, 1);
- if (res !=3D 1) goto ioerror;
- /* res =3D=3D 1 */
- if (ch =3D=3D '\n') return False;
- if (ch !=3D 'N' && ch !=3D 'n' && ch !=3D 'Y' && ch !=3D 'y'=20
- && ch !=3D 'C' && ch !=3D 'c') goto again;
-
- res =3D VG_(read)(VG_(clo_input_fd), &ch2, 1);
- if (res !=3D 1) goto ioerror;
- if (ch2 !=3D '\n') goto again;
-
- /* No, don't want to do action. */
- if (ch =3D=3D 'n' || ch =3D=3D 'N') return False;
- /* Yes, want to do action. */
- if (ch =3D=3D 'y' || ch =3D=3D 'Y') return True;
- /* No, don't want to do action, and don't ask again either. */
- vg_assert(ch =3D=3D 'c' || ch =3D=3D 'C');
-
- ioerror:
- *clo =3D False;
- return False;
-}
-
-
-/* Construct an error */
-static __inline__
-void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a=
,
- Char* s, void* extra, ExeContext* where )
-{
- tl_assert(tid < VG_N_THREADS);
-
- /* Core-only parts */
- err->next =3D NULL;
- err->supp =3D NULL;
- err->count =3D 1;
- err->tid =3D tid;
- if (NULL =3D=3D where)
- err->where =3D VG_(record_ExeContext)( tid );
- else
- err->where =3D where;
-
- /* Tool-relevant parts */
- err->ekind =3D ekind;
- err->addr =3D a;
- err->extra =3D extra;
- err->string =3D s;
-
- /* sanity... */
- vg_assert( tid < VG_N_THREADS );
-}
-
-static void printSuppForIp(UInt n, Addr ip)
-{
- static UChar buf[VG_ERRTXT_LEN];
-
- if ( VG_(get_fnname_nodemangle) (ip, buf, VG_ERRTXT_LEN) ) {
- VG_(printf)(" fun:%s\n", buf);
- } else if ( VG_(get_objname)(ip, buf+7, VG_ERRTXT_LEN-7) ) {
- VG_(printf)(" obj:%s\n", buf);
- } else {
- VG_(printf)(" ???:??? "
- "# unknown, suppression will not work, sorry\n");
- }
-}
-
-static void gen_suppression(Error* err)
-{
- ExeContext* ec =3D VG_(get_error_where)(err);
- Int stop_at =3D VG_(clo_backtrace_size);
-
- /* At most VG_MAX_SUPP_CALLERS names */
- if (stop_at > VG_MAX_SUPP_CALLERS) stop_at =3D VG_MAX_SUPP_CALLERS;
- vg_assert(stop_at > 0);
-
- VG_(printf)("{\n");
- VG_(printf)(" <insert a suppression name here>\n");
-
- if (ThreadErr =3D=3D err->ekind || MutexErr =3D=3D err->ekind) {
- VG_(printf)(" core:PThread\n");
-
- } else {
- Char* name =3D TL_(get_error_name)(err);
- if (NULL =3D=3D name) {
- VG_(message)(Vg_UserMsg,=20
- "(tool does not allow error to be suppressed)");
- return;
- }
- VG_(printf)(" %s:%s\n", VG_(details).name, name);
- TL_(print_extra_suppression_info)(err);
- }
-
- // Print stack trace elements
- VG_(apply_StackTrace)(printSuppForIp, VG_(extract_StackTrace)(ec), st=
op_at);
-
- VG_(printf)("}\n");
-}
-
-static=20
-void do_actions_on_error(Error* err, Bool allow_db_attach)
-{
- Bool still_noisy =3D True;
-
- /* Perhaps we want a debugger attach at this point? */
- if (allow_db_attach &&
- VG_(is_action_requested)( "Attach to debugger", & VG_(clo_db_atta=
ch) ))=20
- {
- VG_(printf)("starting debugger\n");
- VG_(start_debugger)( err->tid );
- }
- /* Or maybe we want to generate the error's suppression? */
- if (VG_(clo_gen_suppressions) =3D=3D 2
- || (VG_(clo_gen_suppressions) =3D=3D 1
- && VG_(is_action_requested)( "Print suppression",
- &still_noisy ))
- ) {
- gen_suppression(err);
- if (VG_(clo_gen_suppressions) =3D=3D 1 && !still_noisy)
- VG_(clo_gen_suppressions) =3D 0;
- }
-}
-
-/* Shared between VG_(maybe_record_error)() and VG_(unique_error)(),
- just for pretty printing purposes. */
-static Bool is_first_shown_context =3D True;
-
-/* Top-level entry point to the error management subsystem.
- All detected errors are notified here; this routine decides if/when t=
he
- user should see the error. */
-void VG_(maybe_record_error) ( ThreadId tid,=20
- ErrorKind ekind, Addr a, Char* s, void* e=
xtra )
-{
- Error err;
- Error* p;
- Error* p_prev;
- UInt extra_size;
- VgRes exe_res =3D Vg_MedRes;
- static Bool stopping_message =3D False;
- static Bool slowdown_message =3D False;
- static Int n_errs_shown =3D 0;
-
- /* After M_COLLECT_NO_ERRORS_AFTER_SHOWN different errors have
- been found, or M_COLLECT_NO_ERRORS_AFTER_FOUND total errors
- have been found, just refuse to collect any more. This stops
- the burden of the error-management system becoming excessive in
- extremely buggy programs, although it does make it pretty
- pointless to continue the Valgrind run after this point. */
- if (VG_(clo_error_limit)=20
- && (n_errs_shown >=3D M_COLLECT_NO_ERRORS_AFTER_SHOWN
- || n_errs_found >=3D M_COLLECT_NO_ERRORS_AFTER_FOUND)) {
- if (!stopping_message) {
- VG_(message)(Vg_UserMsg, "");
-
- if (n_errs_shown >=3D M_COLLECT_NO_ERRORS_AFTER_SHOWN) {
- VG_(message)(Vg_UserMsg,=20
- "More than %d different errors detected. "
- "I'm not reporting any more.",
- M_COLLECT_NO_ERRORS_AFTER_SHOWN );
- } else {
- VG_(message)(Vg_UserMsg,=20
- "More than %d total errors detected. "
- "I'm not reporting any more.",
- M_COLLECT_NO_ERRORS_AFTER_FOUND );
- }
-
- VG_(message)(Vg_UserMsg,=20
- "Final error counts will be inaccurate. Go fix your program=
!");
- VG_(message)(Vg_UserMsg,=20
- "Rerun with --error-limit=3Dno to disable this cutoff. Note=
");
- VG_(message)(Vg_UserMsg,=20
- "that errors may occur in your program without prior warning=
from");
- VG_(message)(Vg_UserMsg,=20
- "Valgrind, because errors are no longer being displayed.");
- VG_(message)(Vg_UserMsg, "");
- stopping_message =3D True;
- }
- return;
- }
-
- /* After M_COLLECT_ERRORS_SLOWLY_AFTER different errors have
- been found, be much more conservative about collecting new
- ones. */
- if (n_errs_shown >=3D M_COLLECT_ERRORS_SLOWLY_AFTER) {
- exe_res =3D Vg_LowRes;
- if (!slowdown_message) {
- VG_(message)(Vg_UserMsg, "");
- VG_(message)(Vg_UserMsg,=20
- "More than %d errors detected. Subsequent errors",
- M_COLLECT_ERRORS_SLOWLY_AFTER);
- VG_(message)(Vg_UserMsg,=20
- "will still be recorded, but in less detail than before.");
- slowdown_message =3D True;
- }
- }
-
- /* Build ourselves the error */
- construct_error ( &err, tid, ekind, a, s, extra, NULL );
-
- /* First, see if we've got an error record matching this one. */
- p =3D errors;
- p_prev =3D NULL;
- while (p !=3D NULL) {
- if (eq_Error(exe_res, p, &err)) {
- /* Found it. */
- p->count++;
- if (p->supp !=3D NULL) {
- /* Deal correctly with suppressed errors. */
- p->supp->count++;
- n_errs_suppressed++; =20
- } else {
- n_errs_found++;
- }
-
- /* Move p to the front of the list so that future searches
- for it are faster. */
- if (p_prev !=3D NULL) {
- vg_assert(p_prev->next =3D=3D p);
- p_prev->next =3D p->next;
- p->next =3D errors;
- errors =3D p;
- }
-
- return;
- }
- p_prev =3D p;
- p =3D p->next;
- }
-
- /* Didn't see it. Copy and add. */
-
- /* OK, we're really going to collect it. The context is on the stack=
and
- will disappear shortly, so we must copy it. First do the main
- (non-`extra') part.
- =20
- Then TL_(update_extra) can update the `extra' part. This is for w=
hen
- there are more details to fill in which take time to work out but
- don't affect our earlier decision to include the error -- by
- postponing those details until now, we avoid the extra work in the
- case where we ignore the error. Ugly.
-
- Then, if there is an `extra' part, copy it too, using the size tha=
t
- TL_(update_extra) returned. Also allow for people using the void*
- extra field for a scalar value like an integer.
- */
-
- /* copy main part */
- p =3D VG_(arena_malloc)(VG_AR_ERRORS, sizeof(Error));
- *p =3D err;
-
- /* update `extra' */
- switch (ekind) {
- // case ThreadErr:
- // case MutexErr:
- // vg_assert(VG_(needs).core_errors);
- // extra_size =3D VG_(tm_error_update_extra)(p);
- // break;
- default:
- vg_assert(VG_(needs).tool_errors);
- extra_size =3D TL_(update_extra)(p);
- break;
- }
-
- /* copy block pointed to by `extra', if there is one */
- if (NULL !=3D p->extra && 0 !=3D extra_size) {=20
- void* new_extra =3D VG_(malloc)(extra_size);
- VG_(memcpy)(new_extra, p->extra, extra_size);
- p->extra =3D new_extra;
- }
-
- p->next =3D errors;
- p->supp =3D is_suppressible_error(&err);
- errors =3D p;
- if (p->supp =3D=3D NULL) {
- n_errs_found++;
- if (!is_first_shown_context)
- VG_(message)(Vg_UserMsg, "");
- pp_Error(p, False);
- is_first_shown_context =3D False;
- n_errs_shown++;
- do_actions_on_error(p, /*allow_db_attach*/True);
- } else {
- n_errs_suppressed++;
- p->supp->count++;
- }
-}
-
-/* Second top-level entry point to the error management subsystem, for
- errors that the tool wants to report immediately, eg. because they're
- guaranteed to only happen once. This avoids all the recording and
- comparing stuff. But they can be suppressed; returns True if it is
- suppressed. Bool `print_error' dictates whether to print the error.=20
- Bool `count_error' dictates whether to count the error in n_errs_foun=
d.
-*/
-Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
- void* extra, ExeContext* where, Bool print_erro=
r,
- Bool allow_db_attach, Bool count_error )
-{
- Error err;
-
- /* Build ourselves the error */
- construct_error ( &err, tid, ekind, a, s, extra, where );
-
- /* Unless it's suppressed, we're going to show it. Don't need to mak=
e
- a copy, because it's only temporary anyway.
-
- Then update the `extra' part with TL_(update_extra), because that =
can
- have an affect on whether it's suppressed. Ignore the size return
- value of TL_(update_extra), because we're not copying `extra'. */
- (void)TL_(update_extra)(&err);
-
- if (NULL =3D=3D is_suppressible_error(&err)) {
- if (count_error)
- n_errs_found++;
-
- if (print_error) {
- if (!is_first_shown_context)
- VG_(message)(Vg_UserMsg, "");
- pp_Error(&err, False);
- is_first_shown_context =3D False;
- }
- do_actions_on_error(&err, allow_db_attach);
-
- return False;
-
- } else {
- n_errs_suppressed++;
- return True;
- }
-}
-
-
-/*------------------------------------------------------------*/
-/*--- Exported fns ---*/
-/*------------------------------------------------------------*/
-
-/* This is called not from generated code but from the scheduler */
-void VG_(show_all_errors) ( void )
-{
- Int i, n_min;
- Int n_err_contexts, n_supp_contexts;
- Error *p, *p_min;
- Supp *su;
- Bool any_supp;
-
- if (VG_(clo_verbosity) =3D=3D 0)
- return;
-
- n_err_contexts =3D 0;
- for (p =3D errors; p !=3D NULL; p =3D p->next) {
- if (p->supp =3D=3D NULL)
- n_err_contexts++;
- }
-
- n_supp_contexts =3D 0;
- for (su =3D suppressions; su !=3D NULL; su =3D su->next) {
- if (su->count > 0)
- n_supp_contexts++;
- }
- VG_(message)(Vg_UserMsg,
- "ERROR SUMMARY: "
- "%d errors from %d contexts (suppressed: %d from %d)",
- n_errs_found, n_err_contexts,=20
- ...
[truncated message content] |
|
From: <js...@ac...> - 2005-04-19 03:03:21
|
Nightly build on phoenix ( SuSE 9.1 ) started at 2005-04-19 03:50:00 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow insn_mmx: valgrind ./insn_mmx insn_mmxext: (skipping, prereq failed: ../../../tests/cputest x86-mmxext) insn_sse: valgrind ./insn_sse insn_sse2: (skipping, prereq failed: ../../../tests/cputest x86-sse2) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 201 tests, 5 stderr failures, 0 stdout failures ================= memcheck/tests/pth_once (stderr) memcheck/tests/scalar (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/writev (stderr) corecheck/tests/fdleak_fcntl (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <to...@co...> - 2005-04-19 02:36:11
|
Nightly build on dunsmere ( athlon, Fedora Core 3 ) started at 2005-04-19 03:30:04 BST Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 185 tests, 78 stderr failures, 2 stdout failures ================= memcheck/tests/addressable (stderr) memcheck/tests/badaddrvalue (stderr) memcheck/tests/badfree-2trace (stderr) memcheck/tests/badfree (stderr) memcheck/tests/badjump (stderr) memcheck/tests/badjump2 (stderr) memcheck/tests/badloop (stderr) memcheck/tests/badpoll (stderr) memcheck/tests/badrw (stderr) memcheck/tests/brk (stderr) memcheck/tests/brk2 (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/clientperm (stderr) memcheck/tests/custom_alloc (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/doublefree (stderr) memcheck/tests/error_counts (stdout) memcheck/tests/errs1 (stderr) memcheck/tests/execve (stderr) memcheck/tests/execve2 (stderr) memcheck/tests/exitprog (stderr) memcheck/tests/fprw (stderr) memcheck/tests/fwrite (stderr) memcheck/tests/inits (stderr) memcheck/tests/inline (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/malloc1 (stderr) memcheck/tests/malloc2 (stderr) memcheck/tests/malloc3 (stderr) memcheck/tests/manuel1 (stderr) memcheck/tests/manuel2 (stderr) memcheck/tests/manuel3 (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/memalign2 (stderr) memcheck/tests/memalign_test (stderr) memcheck/tests/memcmptest (stderr) memcheck/tests/mempool (stderr) memcheck/tests/metadata (stderr) memcheck/tests/mismatches (stderr) memcheck/tests/mmaptest (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/nanoleak_supp (stderr) memcheck/tests/new_nothrow (stderr) memcheck/tests/new_override (stderr) memcheck/tests/null_socket (stderr) memcheck/tests/overlap (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/post-syscall (stderr) memcheck/tests/realloc1 (stderr) memcheck/tests/realloc2 (stderr) memcheck/tests/realloc3 (stderr) memcheck/tests/scalar (stderr) memcheck/tests/scalar_exit_group (stderr) memcheck/tests/scalar_fork (stderr) memcheck/tests/scalar_supp (stderr) memcheck/tests/scalar_vfork (stderr) memcheck/tests/sigaltstack (stderr) memcheck/tests/signal2 (stderr) memcheck/tests/sigprocmask (stderr) memcheck/tests/str_tester (stderr) memcheck/tests/supp1 (stderr) memcheck/tests/supp2 (stderr) memcheck/tests/suppfree (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/toobig-allocs (stderr) memcheck/tests/trivialleak (stderr) memcheck/tests/vgtest_ume (stderr) memcheck/tests/weirdioctl (stderr) memcheck/tests/writev (stderr) memcheck/tests/x86/fpeflags (stderr) memcheck/tests/x86/pushfpopf (stderr) memcheck/tests/x86/tronical (stderr) memcheck/tests/zeropage (stderr) none/tests/faultstatus (stderr) none/tests/selfrun (stdout) none/tests/selfrun (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:30:48
|
Nightly build on audi ( i686, Red Hat 9 ) started at 2005-04-19 03:25:01 BST Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 184 tests, 3 stderr failures, 0 stdout failures ================= memcheck/tests/scalar (stderr) none/tests/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <to...@co...> - 2005-04-19 02:26:27
|
Nightly build on dunsmere ( Fedora Core 3 ) started at 2005-04-19 03:20:03 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (skipping, prereq failed: ../../../tests/cputest x86-sse2) int: valgrind ./int sh: line 1: 19556 Segmentation fault VALGRINDLIB=/tmp/valgrind.26240/valgrind/.in_place /tmp/valgrind.26240/valgrind/./coregrind/valgrind --command-line-only=yes --memcheck:leak-check=no --addrcheck:leak-check=no --tool=none ./int >int.stdout.out 2>int.stderr.out pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 207 tests, 4 stderr failures, 0 stdout failures ================= memcheck/tests/execve (stderr) memcheck/tests/execve2 (stderr) memcheck/tests/scalar (stderr) memcheck/tests/scalar_supp (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:25:48
|
Nightly build on ginetta ( i686, Red Hat 8.0 ) started at 2005-04-19 03:20:02 BST Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 183 tests, 4 stderr failures, 0 stdout failures ================= memcheck/tests/scalar (stderr) memcheck/tests/threadederrno (stderr) none/tests/faultstatus (stderr) none/tests/x86/int (stderr) |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:22:48
|
Nightly build on audi ( Red Hat 9 ) started at 2005-04-19 03:15:02 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow fpu_lazy_eflags: valgrind ./fpu_lazy_eflags insn_basic: valgrind ./insn_basic insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (skipping, prereq failed: ../../../tests/cputest x86-sse2) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 206 tests, 1 stderr failure, 0 stdout failures ================= memcheck/tests/scalar (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:20:57
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2005-04-19 03:15:02 BST Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 183 tests, 17 stderr failures, 1 stdout failure ================= memcheck/tests/addressable (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/scalar (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/vgtest_ume (stderr) addrcheck/tests/leak-0 (stderr) addrcheck/tests/leak-cycle (stderr) addrcheck/tests/leak-regroot (stderr) addrcheck/tests/leak-tree (stderr) none/tests/faultstatus (stderr) none/tests/x86/int (stderr) none/tests/yield (stdout) |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:16:27
|
Nightly build on ginetta ( Red Hat 8.0 ) started at 2005-04-19 03:10:01 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow insn_cmov: valgrind ./insn_cmov insn_fpu: valgrind ./insn_fpu insn_mmx: valgrind ./insn_mmx insn_mmxext: valgrind ./insn_mmxext insn_sse: valgrind ./insn_sse insn_sse2: (skipping, prereq failed: ../../../tests/cputest x86-sse2) int: valgrind ./int pushpopseg: valgrind ./pushpopseg rcl_assert: valgrind ./rcl_assert seg_override: valgrind ./seg_override -- Finished tests in none/tests/x86 ------------------------------------ yield: valgrind ./yield -- Finished tests in none/tests ---------------------------------------- == 205 tests, 3 stderr failures, 0 stdout failures ================= memcheck/tests/pth_once (stderr) memcheck/tests/scalar (stderr) memcheck/tests/threadederrno (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:11:41
|
Nightly build on alvis ( Red Hat 7.3 ) started at 2005-04-19 03:05:01 BST Checking out source tree ... done Configuring ... done Building ... done Running regression tests ... done Last 20 lines of log.verbose follow == 205 tests, 17 stderr failures, 0 stdout failures ================= memcheck/tests/addressable (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/distinguished-writes (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/pth_once (stderr) memcheck/tests/scalar (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/vgtest_ume (stderr) addrcheck/tests/leak-0 (stderr) addrcheck/tests/leak-cycle (stderr) addrcheck/tests/leak-regroot (stderr) addrcheck/tests/leak-tree (stderr) make: *** [regtest] Error 1 |
|
From: Tom H. <th...@cy...> - 2005-04-19 02:03:01
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2005-04-19 03:00:03 BST Checking out vex source tree ... done Building vex ... done Checking out valgrind source tree ... done Configuring valgrind ... done Building valgrind ... done Running regression tests ... failed Regression test results follow == 165 tests, 82 stderr failures, 22 stdout failures ================= memcheck/tests/addressable (stdout) memcheck/tests/addressable (stderr) memcheck/tests/badaddrvalue (stdout) memcheck/tests/badaddrvalue (stderr) memcheck/tests/badfree-2trace (stderr) memcheck/tests/badfree (stderr) memcheck/tests/badjump (stderr) memcheck/tests/badjump2 (stderr) memcheck/tests/badloop (stderr) memcheck/tests/badpoll (stderr) memcheck/tests/badrw (stderr) memcheck/tests/brk (stderr) memcheck/tests/brk2 (stderr) memcheck/tests/buflen_check (stderr) memcheck/tests/clientperm (stdout) memcheck/tests/clientperm (stderr) memcheck/tests/custom_alloc (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/doublefree (stderr) memcheck/tests/error_counts (stdout) memcheck/tests/errs1 (stderr) memcheck/tests/execve (stderr) memcheck/tests/execve2 (stderr) memcheck/tests/exitprog (stderr) memcheck/tests/fprw (stderr) memcheck/tests/fwrite (stdout) memcheck/tests/fwrite (stderr) memcheck/tests/inits (stderr) memcheck/tests/inline (stdout) memcheck/tests/inline (stderr) memcheck/tests/leak-0 (stderr) memcheck/tests/leak-cycle (stderr) memcheck/tests/leak-regroot (stderr) memcheck/tests/leak-tree (stderr) memcheck/tests/leakotron (stdout) memcheck/tests/malloc1 (stderr) memcheck/tests/malloc2 (stderr) memcheck/tests/malloc3 (stdout) memcheck/tests/malloc3 (stderr) memcheck/tests/manuel1 (stdout) memcheck/tests/manuel1 (stderr) memcheck/tests/manuel2 (stdout) memcheck/tests/manuel2 (stderr) memcheck/tests/manuel3 (stderr) memcheck/tests/match-overrun (stderr) memcheck/tests/memalign_test (stderr) memcheck/tests/memcmptest (stdout) memcheck/tests/memcmptest (stderr) memcheck/tests/mempool (stderr) memcheck/tests/metadata (stdout) memcheck/tests/metadata (stderr) memcheck/tests/mismatches (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/new_override (stdout) memcheck/tests/new_override (stderr) memcheck/tests/overlap (stdout) memcheck/tests/overlap (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/post-syscall (stdout) memcheck/tests/post-syscall (stderr) memcheck/tests/realloc3 (stderr) memcheck/tests/scalar (stderr) memcheck/tests/scalar_exit_group (stderr) memcheck/tests/scalar_fork (stderr) memcheck/tests/scalar_supp (stderr) memcheck/tests/scalar_vfork (stderr) memcheck/tests/sigaltstack (stderr) memcheck/tests/signal2 (stdout) memcheck/tests/signal2 (stderr) memcheck/tests/sigprocmask (stderr) memcheck/tests/supp2 (stderr) memcheck/tests/suppfree (stderr) memcheck/tests/threadederrno (stdout) memcheck/tests/toobig-allocs (stderr) memcheck/tests/trivialleak (stderr) memcheck/tests/vgtest_ume (stderr) memcheck/tests/weirdioctl (stdout) memcheck/tests/weirdioctl (stderr) memcheck/tests/writev (stderr) memcheck/tests/zeropage (stdout) addrcheck/tests/addressable (stdout) addrcheck/tests/addressable (stderr) addrcheck/tests/badrw (stderr) addrcheck/tests/fprw (stderr) addrcheck/tests/leak-0 (stderr) addrcheck/tests/leak-cycle (stderr) addrcheck/tests/leak-regroot (stderr) addrcheck/tests/leak-tree (stderr) addrcheck/tests/overlap (stdout) addrcheck/tests/overlap (stderr) addrcheck/tests/toobig-allocs (stderr) corecheck/tests/fdleak_cmsg (stderr) corecheck/tests/fdleak_creat (stderr) corecheck/tests/fdleak_dup (stderr) corecheck/tests/fdleak_dup2 (stderr) corecheck/tests/fdleak_fcntl (stderr) corecheck/tests/fdleak_ipv4 (stderr) corecheck/tests/fdleak_open (stderr) corecheck/tests/fdleak_pipe (stderr) corecheck/tests/fdleak_socketpair (stderr) massif/tests/toobig-allocs (stderr) none/tests/faultstatus (stderr) none/tests/selfrun (stdout) none/tests/selfrun (stderr) |