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: Rex W. <wa...@gm...> - 2005-04-24 21:52:12
|
THanks. that is all I wanted to know. I wanted to know if the same principle used in callgrind could be used for dullard. THanks again. Rex. On 4/24/05, Josef Weidendorfer <Jos...@gm...> wrote: > On Friday 22 April 2005 15:48, Rex Walburn wrote: > > Hi > > You had mentioned the macro CALLGRIND_START_INSTRUMENTATION that can > > be used to start instrumentation at a particular point in the source > > code. So can I use this same macro for another tool like "dullard" > > which dumps out memory traces for an executable ? >=20 > Sorry, no. > This macro will be ignored when run with a Valgrind tool other than callg= rind. > You would have to add similar support to Dullard. > But perhaps it would be good to generalize this for all tools: A tool wit= h > different instrumentation levels should be able to specify this to Valgri= nd > core, which will handle all the rest, i.e. flush the translation cache on= a > change. Neverless, "dullard" would have to be changed to support such an > Valgrind extension. >=20 > Josef >=20 > > > > THanks > > Rex > |
|
From: Julian S. <js...@ac...> - 2005-04-24 18:18:18
|
> > Add intercepts for operator new(unsigned long) and operator
> > new[](unsigned long). The 32-bit ones take unsigned int args, not
> > unsigned longs, and so the existing name-set did not capture them.
>
> The parameters are actually std::size_t, which should be 32-bits on 32-bit
> platforms and 64-bits on 64-bit platforms, so I'm confused by this
> change...
Problem is this. If you compile this
int* p1 = new int;
int* p2 = new int[10];
on x86, the resulting assembly/object contains calls to _Znwj and _Znaj
respectively. But on amd64, those calls are to _Znwm and _Znam
instead. If you offer up those 4 symbols to c++filt, it says they are
operator new(unsigned int) (..j variants)
operator new[](unsigned int)
operator new(unsigned long) (..m variants)
operator new[](unsigned long)
from which I assume that the C++ name mangler dereferences all type
aliases -- which size_t must be -- before generating the mangled name.
Hence you end up with different names on the differently-word-sized
platforms.
J
|
|
From: Josef W. <Jos...@gm...> - 2005-04-24 18:02:03
|
On Friday 22 April 2005 15:48, Rex Walburn wrote: > Hi > You had mentioned the macro CALLGRIND_START_INSTRUMENTATION that can > be used to start instrumentation at a particular point in the source > code. So can I use this same macro for another tool like "dullard" > which dumps out memory traces for an executable ? Sorry, no. This macro will be ignored when run with a Valgrind tool other than callgrind. You would have to add similar support to Dullard. But perhaps it would be good to generalize this for all tools: A tool with different instrumentation levels should be able to specify this to Valgrind core, which will handle all the rest, i.e. flush the translation cache on a change. Neverless, "dullard" would have to be changed to support such an Valgrind extension. Josef > > THanks > Rex |
|
From: Josef W. <Jos...@gm...> - 2005-04-24 18:02:02
|
On Friday 22 April 2005 16:59, Benoit Peccatte wrote: > > How do you detect source lines with code never executed? > > Valgrind reads a part of the dwarf informations (which are available > when you compile with -g option). Debug informations contain a list of > locations where code can be found. I read all of them for each segment > and thus know what could be run. Ah, good. I didn't know you can iterate over debug info in a Valgrind tool. > That's a good idea, I'm reading the documentation. > > But I think I may make a simple interface to be able to do it without > kcachegrind. That will work automatically, because KCachegrind will be able to read the data without problems ;-) > > I would chose the following events related to a source line > > 1) "Line has debug info" (i.e. relevant code for coverage): Yes 1, No 0 > > 2) "Line was NOT executed" Yes: 1, No: 0 > > As cg_annotate sorts according highest values, the "NOT" in 2) is > > important for the overview: You get the sorted list of function where a > > lot of lines are never executed. > > We don't know when a line don't have debug info, we even don't know that it > exist. Yes of course. The programmer has to compile with -g. The thing is, that you want to know which lines have debug info. And you know about this. So I was a bit misleading: Every source line listed in the output of the tool would have a "1" for 1). I think you need this to calculate percentage, and still use the cachegrind format: It makes no sense to write percentage values into the output, because cg_annotate/KCachegrind will sum up events of lines to get the event count of a function, and summing makes no sense with percentage values. To be able to use the cachegrind format, cg_annotate will have to calculate the ratio. > What about an event like this : > events: Executed ExecCount > > Executed is 0 or 1 whereas ExecCount give the number of time each line was > executed. How do you get the percentage of executed lines in a function from this? Not that cg_annotate will sum up this itself from the events of the lines in the function, you can not specify this seperately. With my suggestion 1), this would give the number of lines with debug info in a function. > > It would be good here to define derived events like "2) divided by 1)", > > to get the percentage values calculated. This is interesting for > > cachegrind itself (e.g. cache hit ratio). I am sure a patch for > > cg_annotate is welcome. In KCachegrind, derived metrics are already > > possible, but only with operator "+". I would add "/" for you ;-) > > And callgrind even extends cachegrind's format to allow to specify > > derived metric formulas. > > I don't really understand here. Should I calculate the percentage withing > the tool ? My suggestion is to calculate the percentage in cg_annotate. > How can I specify or get values for summary such as percentage > of executed code by function, by file or by soname ? As said above, cg_annotate sums up this itself. The same with KCachegrind. The formula could be specified on the command line, or given in the data file. KCachegrind supports this by adding a line in the header like event: Coverage = Executed / DebugInfo and will calculate everything itself. But note that currently there is no support for parsing "/" in formulas. > > > > > 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. > > > > > > Too bad, should I use a DWARF reader library ? > > > > A long time ago I had a local patch for prefixing every source file name > > with the directory name while loading the debug info... > > This is exactly whan I need, I would be glad if you could find it. I just looked, and I think it was for STABS. See http://kcachegrind.sourceforge.net/patch-0.2b-valgrind-1.0.4.gz, the part for vg_symtab2.c. > > > But is this needed? > > With cg_annotate / KCachegrind you can specify the directories where to > > look for source. Of course there is a problem if a program has source > > files with the same name. > > Yes it is, I work on a big project with many sub directories. I don't > want the user to find himself where is each source file, especially if > the software can do it automaticly. With KCachegrind, you only have to specify the base of the source tree, it will recurse into subdirs automatically. I thought the same is true for cg_annotate, but if not, this should be easy to add. Josef |
|
From: <sv...@va...> - 2005-04-24 14:34:47
|
Author: sewardj Date: 2005-04-24 15:34:42 +0100 (Sun, 24 Apr 2005) New Revision: 3558 Modified: trunk/coregrind/README_MODULES.txt Log: Relax the requirement that a pub_tool_<modulename>.h file must exist even if it defines nothing. That's a bit silly. Modified: trunk/coregrind/README_MODULES.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/README_MODULES.txt 2005-04-24 14:31:29 UTC (rev 3557) +++ trunk/coregrind/README_MODULES.txt 2005-04-24 14:34:42 UTC (rev 3558) @@ -34,16 +34,15 @@ coregrind/pub_core_foo.h =20 pub_tool_foo.h describes that part of the module's functionality that -is visible to tools. Hopefully this can be minimal or zero. The file -must still exist even if it defines nothing. +is visible to tools. Hopefully this can be minimal or zero. If there +is nothing to visible to tool, pub_tool_foo.h can be omitted. =20 pub_core_foo.h describes functionality that is visible to other modules in the core. This is a strict superset of the visible-to-tool -functionality. +functionality. Consequently, pub_core_foo.h *must* #include +pub_tool_foo.h, if it exists. pub_tool_foo.h *must not* #include +pub_core_foo.h, nor any other pub_core_ header for that matter. =20 -Consequently, pub_core_foo.h may #include pub_tool_foo.h, but not the -other way round. - No module may include the private headers of any other module. If a type/enum/function/struct/whatever is stated in neither include/pub_tool_foo.h nor coregrind/pub_core_foo.h then module 'foo' |
|
From: <sv...@va...> - 2005-04-24 14:31:34
|
Author: sewardj
Date: 2005-04-24 15:31:29 +0100 (Sun, 24 Apr 2005)
New Revision: 3557
Modified:
trunk/coregrind/amd64-linux/syscalls.c
trunk/coregrind/m_sigframe/sigframe-amd64-linux.c
trunk/coregrind/m_sigframe/sigframe-x86-linux.c
Log:
Make amd64-linux build again after m_sigframe hackery.
Modified: trunk/coregrind/amd64-linux/syscalls.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/amd64-linux/syscalls.c 2005-04-24 14:18:14 UTC (rev 3=
556)
+++ trunk/coregrind/amd64-linux/syscalls.c 2005-04-24 14:31:29 UTC (rev 3=
557)
@@ -30,6 +30,7 @@
=20
#include "core.h"
#include "ume.h" /* for jmp_with_stack */
+#include "pub_core_sigframe.h"
=20
=20
/* COPIED FROM /usr/include/asm-i386/prctl.h (amd64-linux) */
@@ -545,7 +546,7 @@
something goes wrong in the sigreturn */
VGA_(restart_syscall)(&tst->arch);
=20
- VGA_(signal_return)(tid, True);
+ VG_(sigframe_destroy)(tid, True);
=20
/* Keep looking for signals until there are none */
VG_(poll_signals)(tid);
Modified: trunk/coregrind/m_sigframe/sigframe-amd64-linux.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/m_sigframe/sigframe-amd64-linux.c 2005-04-24 14:18:14=
UTC (rev 3556)
+++ trunk/coregrind/m_sigframe/sigframe-amd64-linux.c 2005-04-24 14:31:29=
UTC (rev 3557)
@@ -1,6 +1,7 @@
=20
/*--------------------------------------------------------------------*/
-/*--- Arch-specific signals stuff. amd64/signals.c ---*/
+/*--- Create/destroy signal delivery frames. ---*/
+/*--- sigframe-amd64-linux.c ---*/
/*--------------------------------------------------------------------*/
=20
/*
@@ -29,6 +30,7 @@
*/
=20
#include "core.h"
+#include "pub_core_sigframe.h"
=20
#include "libvex_guest_amd64.h"
=20
@@ -36,15 +38,10 @@
/* This module creates and removes signal frames for signal deliveries
on amd64-linux.
=20
- FIXME: Note that this file is in the wrong place. It is marked as
- amd64 specific, but in fact it is specific to both amd64 and linux.
- There is nothing that ensures that (eg) amd64-netbsd will have the
- same signal frame layout as Linux.
+ Note, this file contains kernel-specific knowledge in the form of
+ 'struct rt_sigframe'. How does that relate to the vki kernel
+ interface stuff?
=20
- Note also, this file contains kernel-specific knowledge in the
- form of 'struct rt_sigframe'. How does that relate to the vki
- kernel interface stuff?
-
A 'struct rtsigframe' is pushed onto the client's stack. This
contains a subsidiary vki_ucontext. That holds the vcpu's state
across the signal, so that the sighandler can mess with the vcpu
@@ -478,11 +475,13 @@
}
=20
=20
-void VGA_(push_signal_frame)(ThreadId tid, Addr rsp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer)
+void VG_(sigframe_create)( ThreadId tid,=20
+ Addr rsp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler,=20
+ UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer )
{
Addr rsp;
struct rt_sigframe *frame;
@@ -584,7 +583,7 @@
}
=20
=20
-void VGA_(signal_return)(ThreadId tid, Bool isRT)
+void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
{
Addr rsp;
ThreadState* tst;
@@ -673,7 +672,7 @@
//:: {
//:: VG_(memcpy)(xfpu, arch->m_sse.state, sizeof(*xfpu));
//:: }
-//::=20
-//:: /*-----------------------------------------------------------------=
---*/
-//:: /*--- end =
---*/
-//:: /*-----------------------------------------------------------------=
---*/
+
+/*--------------------------------------------------------------------*/
+/*--- end sigframe-amd64-linux.c ---*/
+/*--------------------------------------------------------------------*/
Modified: trunk/coregrind/m_sigframe/sigframe-x86-linux.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/m_sigframe/sigframe-x86-linux.c 2005-04-24 14:18:14 U=
TC (rev 3556)
+++ trunk/coregrind/m_sigframe/sigframe-x86-linux.c 2005-04-24 14:31:29 U=
TC (rev 3557)
@@ -31,6 +31,7 @@
=20
#include "core.h"
#include "pub_core_sigframe.h"
+
#include "libvex_guest_x86.h"
=20
=20
|
|
From: <sv...@va...> - 2005-04-24 14:18:20
|
Author: sewardj
Date: 2005-04-24 15:18:14 +0100 (Sun, 24 Apr 2005)
New Revision: 3556
Added:
trunk/coregrind/m_sigframe/
trunk/coregrind/m_sigframe/Makefile.am
trunk/coregrind/m_sigframe/sigframe-amd64-linux.c
trunk/coregrind/m_sigframe/sigframe-arm-linux.c
trunk/coregrind/m_sigframe/sigframe-x86-linux.c
trunk/coregrind/pub_core_sigframe.h
Removed:
trunk/coregrind/amd64/signals.c
trunk/coregrind/arm/signals.c
trunk/coregrind/x86/signals.c
Modified:
trunk/configure.in
trunk/coregrind/Makefile.am
trunk/coregrind/amd64/Makefile.am
trunk/coregrind/amd64/core_arch.h
trunk/coregrind/arm/Makefile.am
trunk/coregrind/core.h
trunk/coregrind/vg_signals.c
trunk/coregrind/x86-linux/syscalls.c
trunk/coregrind/x86/Makefile.am
trunk/coregrind/x86/core_arch.h
Log:
Create a new module, "sigframe", responsible for creating/destroying
signal frames. This commit looks worse than it is -- really just a
load of moving-code-around.
This is the first multiple-implementation module, in that it has a
single interface (pub_core_sigframe.h) but multiple implementations,
depending on the os-cpu pair. All the grotty details are hidden in
the implementation in m_sigframe/; callers need be aware only of the
interface. Yay.
Modified: trunk/configure.in
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/configure.in 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/configure.in 2005-04-24 14:18:14 UTC (rev 3556)
@@ -394,6 +394,7 @@
auxprogs/Makefile
coregrind/Makefile=20
coregrind/demangle/Makefile=20
+ coregrind/m_sigframe/Makefile=20
coregrind/amd64/Makefile
coregrind/arm/Makefile
coregrind/x86/Makefile
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-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -4,9 +4,14 @@
## When building, we are only interested in the current arch/OS/platform=
.
## But when doing 'make dist', we are interested in every arch/OS/platfo=
rm.
## That's what DIST_SUBDIRS specifies.
-SUBDIRS =3D $(VG_ARCH) $(VG_OS) $(VG_PLATFORM) demangle=
.
-DIST_SUBDIRS =3D $(VG_ARCH_ALL) $(VG_OS_ALL) $(VG_PLATFORM_ALL) demangle=
.
+SUBDIRS =3D \
+ $(VG_ARCH) $(VG_OS) $(VG_PLATFORM) \
+ m_sigframe demangle .
=20
+DIST_SUBDIRS =3D \
+ $(VG_ARCH_ALL) $(VG_OS_ALL) $(VG_PLATFORM_ALL) \
+ m_sigframe demangle .
+
AM_CPPFLAGS +=3D -DVG_LIBDIR=3D"\"$(valdir)"\" -I$(srcdir)/demangle \
-DKICKSTART_BASE=3D@KICKSTART_BASE@ \
-DVG_PLATFORM=3D"\"$(VG_PLATFORM)"\"
@@ -87,6 +92,7 @@
## libplatform.a must be before libarch.a and libos.a, it seems.
stage2_extra=3D \
demangle/libdemangle.a \
+ m_sigframe/libsigframe.a \
${VG_PLATFORM}/libplatform.a \
${VG_ARCH}/libarch.a \
${VG_OS}/libos.a \
Modified: trunk/coregrind/amd64/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/amd64/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -21,7 +21,6 @@
cpuid.S \
helpers.S \
dispatch.S \
- signals.c \
jmp_with_stack.c \
state.c
=20
Modified: trunk/coregrind/amd64/core_arch.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/amd64/core_arch.h 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/core_arch.h 2005-04-24 14:18:14 UTC (rev 3556)
@@ -127,12 +127,7 @@
// Base address of client address space.
#define VGA_CLIENT_BASE 0x0ul
=20
-/* ---------------------------------------------------------------------
- Signal stuff (should be plat)
- ------------------------------------------------------------------ */
=20
-void VGA_(signal_return)(ThreadId tid, Bool isRT);
-
#endif // __AMD64_CORE_ARCH_H
=20
/*--------------------------------------------------------------------*/
Deleted: trunk/coregrind/amd64/signals.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/amd64/signals.c 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/amd64/signals.c 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1,679 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Arch-specific signals stuff. amd64/signals.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Nicholas Nethercote
- nj...@ca...
-
- 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 "libvex_guest_amd64.h"
-
-
-/* This module creates and removes signal frames for signal deliveries
- on amd64-linux.
-
- FIXME: Note that this file is in the wrong place. It is marked as
- amd64 specific, but in fact it is specific to both amd64 and linux.
- There is nothing that ensures that (eg) amd64-netbsd will have the
- same signal frame layout as Linux.
-
- Note also, this file contains kernel-specific knowledge in the
- form of 'struct rt_sigframe'. How does that relate to the vki
- kernel interface stuff?
-
- A 'struct rtsigframe' is pushed onto the client's stack. This
- contains a subsidiary vki_ucontext. That holds the vcpu's state
- across the signal, so that the sighandler can mess with the vcpu
- state if it really wants.
-
- FIXME: sigcontexting is basically broken for the moment. When
- delivering a signal, the integer registers and %rflags are
- correctly written into the sigcontext, however the FP and SSE state
- is not. When returning from a signal, only the integer registers
- are restored from the sigcontext; the rest of the CPU state is
- restored to what it was before the signal.
-
- This will be fixed.
-*/
-
-
-/*------------------------------------------------------------*/
-/*--- Signal frame layouts ---*/
-/*------------------------------------------------------------*/
-
-// A structure in which to save the application's registers
-// during the execution of signal handlers.
-
-// In theory, so long as we get the arguments to the handler function
-// right, it doesn't matter what the exact layout of the rest of the
-// frame is. Unfortunately, things like gcc's exception unwinding
-// make assumptions about the locations of various parts of the frame,
-// so we need to duplicate it exactly.
-
-/* Valgrind-specific parts of the signal frame */
-struct vg_sigframe
-{
- /* Sanity check word. */
- UInt magicPI;
-
- UInt handlerflags; /* flags for signal handler */
-
-
- /* Safely-saved version of sigNo, as described above. */
- Int sigNo_private;
-
- /* XXX This is wrong. Surely we should store the shadow values
- into the shadow memory behind the actual values? */
- VexGuestAMD64State vex_shadow;
-
- /* HACK ALERT */
- VexGuestAMD64State vex;
- /* end HACK ALERT */
-
- /* saved signal mask to be restored when handler returns */
- vki_sigset_t mask;
-
- /* Sanity check word. Is the highest-addressed word; do not
- move!*/
- UInt magicE;
-};
-
-struct rt_sigframe
-{
- /* Sig handler's return address */
- Addr retaddr;
-
- /* ucontext */
- struct vki_ucontext uContext;
-
- /* siginfo */
- vki_siginfo_t sigInfo;
- struct _vki_fpstate fpstate;
-
- struct vg_sigframe vg;
-};
-
-
-//:: /*------------------------------------------------------------*/
-//:: /*--- Signal operations ---*/
-//:: /*------------------------------------------------------------*/
-//::=20
-//:: /*=20
-//:: Great gobs of FP state conversion taken wholesale from
-//:: linux/arch/i386/kernel/i387.c
-//:: */
-//::=20
-//:: /*
-//:: * FXSR floating point environment conversions.
-//:: */
-//:: #define X86_FXSR_MAGIC 0x0000
-//::=20
-//:: /*
-//:: * FPU tag word conversions.
-//:: */
-//::=20
-//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
-//:: {
-//:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
-//:: =20
-//:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
-//:: tmp =3D ~twd;
-//:: tmp =3D (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
-//:: /* and move the valid bits to the lower byte. */
-//:: tmp =3D (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
-//:: tmp =3D (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
-//:: tmp =3D (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
-//:: return tmp;
-//:: }
-//::=20
-//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_str=
uct *fxsave )
-//:: {
-//:: struct _vki_fpxreg *st =3D NULL;
-//:: unsigned long twd =3D (unsigned long) fxsave->twd;
-//:: unsigned long tag;
-//:: unsigned long ret =3D 0xffff0000u;
-//:: int i;
-//::=20
-//:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
-//::=20
-//:: for ( i =3D 0 ; i < 8 ; i++ ) {
-//:: if ( twd & 0x1 ) {
-//:: st =3D (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
-//::=20
-//:: switch ( st->exponent & 0x7fff ) {
-//:: case 0x7fff:
-//:: tag =3D 2; /* Special */
-//:: break;
-//:: case 0x0000:
-//:: if ( !st->significand[0] &&
-//:: !st->significand[1] &&
-//:: !st->significand[2] &&
-//:: !st->significand[3] ) {
-//:: tag =3D 1; /* Zero */
-//:: } else {
-//:: tag =3D 2; /* Special */
-//:: }
-//:: break;
-//:: default:
-//:: if ( st->significand[3] & 0x8000 ) {
-//:: tag =3D 0; /* Valid */
-//:: } else {
-//:: tag =3D 2; /* Special */
-//:: }
-//:: break;
-//:: }
-//:: } else {
-//:: tag =3D 3; /* Empty */
-//:: }
-//:: ret |=3D (tag << (2 * i));
-//:: twd =3D twd >> 1;
-//:: }
-//:: return ret;
-//:: }
-//::=20
-//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
-//:: const struct i387_fxsave_struct *fxsave )
-//:: {
-//:: unsigned long env[7];
-//:: struct _vki_fpreg *to;
-//:: struct _vki_fpxreg *from;
-//:: int i;
-//::=20
-//:: env[0] =3D (unsigned long)fxsave->cwd | 0xffff0000ul;
-//:: env[1] =3D (unsigned long)fxsave->swd | 0xffff0000ul;
-//:: env[2] =3D twd_fxsr_to_i387(fxsave);
-//:: env[3] =3D fxsave->fip;
-//:: env[4] =3D fxsave->fcs | ((unsigned long)fxsave->fop << 16);
-//:: env[5] =3D fxsave->foo;
-//:: env[6] =3D fxsave->fos;
-//:: =20
-//:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
-//::=20
-//:: to =3D &buf->_st[0];
-//:: from =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
-//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
-//:: unsigned long __user *t =3D (unsigned long __user *)to;
-//:: unsigned long *f =3D (unsigned long *)from;
-//::=20
-//:: t[0] =3D f[0];
-//:: t[1] =3D f[1];
-//:: to->exponent =3D from->exponent;
-//:: }
-//:: }
-//::=20
-//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsa=
ve,
-//:: const struct _vki_fpstate *buf )
-//:: {
-//:: unsigned long env[7];
-//:: struct _vki_fpxreg *to;
-//:: const struct _vki_fpreg *from;
-//:: int i;
-//:: =09
-//:: VG_(memcpy)(env, buf, 7 * sizeof(long));
-//::=20
-//:: fxsave->cwd =3D (unsigned short)(env[0] & 0xffff);
-//:: fxsave->swd =3D (unsigned short)(env[1] & 0xffff);
-//:: fxsave->twd =3D twd_i387_to_fxsr((unsigned short)(env[2] & 0xfff=
f));
-//:: fxsave->fip =3D env[3];
-//:: fxsave->fop =3D (unsigned short)((env[4] & 0xffff0000ul) >> 16);
-//:: fxsave->fcs =3D (env[4] & 0xffff);
-//:: fxsave->foo =3D env[5];
-//:: fxsave->fos =3D env[6];
-//::=20
-//:: to =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
-//:: from =3D &buf->_st[0];
-//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
-//:: unsigned long *t =3D (unsigned long *)to;
-//:: unsigned long __user *f =3D (unsigned long __user *)from;
-//::=20
-//:: t[0] =3D f[0];
-//:: t[1] =3D f[1];
-//:: to->exponent =3D from->exponent;
-//:: }
-//:: }
-//::=20
-//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vk=
i_fpstate *buf )
-//:: {
-//:: struct i387_fsave_struct *fs =3D ®s->m_sse.fsave;
-//::=20
-//:: fs->status =3D fs->swd;
-//:: VG_(memcpy)(buf, fs, sizeof(*fs));
-//:: }
-//::=20
-//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpst=
ate *buf )
-//:: {
-//:: const struct i387_fxsave_struct *fx =3D ®s->m_sse.fxsave;
-//:: convert_fxsr_to_user( buf, fx );
-//::=20
-//:: buf->status =3D fx->swd;
-//:: buf->magic =3D X86_FXSR_MAGIC;
-//:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct=
));
-//:: }
-//::=20
-//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *bu=
f )
-//:: {
-//:: if ( VG_(have_ssestate) )
-//:: save_i387_fxsave( regs, buf );
-//:: else
-//:: save_i387_fsave( regs, buf );
-//:: }
-//::=20
-//:: static inline void restore_i387_fsave( arch_thread_t *regs, const s=
truct _vki_fpstate __user *buf )
-//:: {
-//:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_s=
truct) );
-//:: }
-//::=20
-//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct =
_vki_fpstate __user *buf )
-//:: {
-//:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],=20
-//:: sizeof(struct i387_fxsave_struct) );
-//:: /* mxcsr reserved bits must be masked to zero for security reaso=
ns */
-//:: regs->m_sse.fxsave.mxcsr &=3D 0xffbf;
-//:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
-//:: }
-//::=20
-//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fp=
state __user *buf )
-//:: {
-//:: if ( VG_(have_ssestate) ) {
-//:: restore_i387_fxsave( regs, buf );
-//:: } else {
-//:: restore_i387_fsave( regs, buf );
-//:: }
-//:: }
-
-
-/*------------------------------------------------------------*/
-/*--- Creating signal frames ---*/
-/*------------------------------------------------------------*/
-
-/* Create a plausible-looking sigcontext from the thread's
- Vex guest state. NOTE: does not fill in the FP or SSE
- bits of sigcontext at the moment.
-*/
-static=20
-void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
- const vki_sigset_t *set,=20
- struct vki_ucontext *uc, struct _vki_fpstate *fpstat=
e)
-{
- ThreadState *tst =3D VG_(get_ThreadState)(tid);
- struct vki_sigcontext *sc =3D &uc->uc_mcontext;
-
- VG_(memset)(uc, 0, sizeof(*uc));
-
- uc->uc_flags =3D 0;
- uc->uc_link =3D 0;
- uc->uc_sigmask =3D *set;
- uc->uc_stack =3D tst->altstack;
- sc->fpstate =3D fpstate;
-
- // FIXME: save_i387(&tst->arch, fpstate);
-
-# define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
- SC2(r8,R8);
- SC2(r9,R9);
- SC2(r10,R10);
- SC2(r11,R11);
- SC2(r12,R12);
- SC2(r13,R13);
- SC2(r14,R14);
- SC2(r15,R15);
- SC2(rdi,RDI);
- SC2(rsi,RSI);
- SC2(rbp,RBP);
- SC2(rbx,RBX);
- SC2(rdx,RDX);
- SC2(rax,RAX);
- SC2(rcx,RCX);
- SC2(rsp,RSP);
-
- SC2(rip,RIP);
- sc->eflags =3D LibVEX_GuestAMD64_get_rflags(&tst->arch.vex);
- // FIXME: SC2(cs,CS);
- // FIXME: SC2(gs,GS);
- // FIXME: SC2(fs,FS);
- /* XXX err */
- /* XXX trapno */
-# undef SC2
-
- sc->cr2 =3D (UWord)si->_sifields._sigfault._addr;
-}
-
-
-#define SET_SIGNAL_RSP(zztid, zzval) \
- SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
- Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr))
-
-
-/* Extend the stack segment downwards if needed so as to ensure the
- new signal frames are mapped to something. Return a Bool
- indicating whether or not the operation was successful.
-*/
-static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
-{
- ThreadId tid =3D tst->tid;
- Segment *stackseg =3D NULL;
-
- if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
- stackseg =3D VG_(find_segment)(addr);
- if (0 && stackseg)
- VG_(printf)("frame=3D%p seg=3D%p-%p\n",
- addr, stackseg->addr, stackseg->addr+stackseg->len);
- }
-
- if (stackseg =3D=3D NULL=20
- || (stackseg->prot & (VKI_PROT_READ|VKI_PROT_WRITE)) =3D=3D 0) {
- VG_(message)(
- Vg_UserMsg,
- "Can't extend stack to %p during signal delivery for thread %d:=
",
- addr, tid);
- if (stackseg =3D=3D NULL)
- VG_(message)(Vg_UserMsg, " no stack segment");
- else
- VG_(message)(Vg_UserMsg, " too small or bad protection modes")=
;
-
- /* set SIGSEGV to default handler */
- VG_(set_default_handler)(VKI_SIGSEGV);
- VG_(synth_fault_mapping)(tid, addr);
-
- /* The whole process should be about to die, since the default
- action of SIGSEGV to kill the whole process. */
- return False;
- }
-
- /* For tracking memory events, indicate the entire frame has been
- allocated. */
- VG_TRACK( new_mem_stack_signal, addr, size );
-
- return True;
-}
-
-
-/* Build the Valgrind-specific part of a signal frame. */
-
-static void build_vg_sigframe(struct vg_sigframe *frame,
- ThreadState *tst,
- const vki_sigset_t *mask,
- UInt flags,
- Int sigNo)
-{
- frame->sigNo_private =3D sigNo;
- frame->magicPI =3D 0x31415927;
- frame->vex_shadow =3D tst->arch.vex_shadow;
- /* HACK ALERT */
- frame->vex =3D tst->arch.vex;
- /* end HACK ALERT */
- frame->mask =3D tst->sig_mask;
- frame->handlerflags =3D flags;
- frame->magicE =3D 0x27182818;
-}
-
-
-static Addr build_rt_sigframe(ThreadState *tst,
- Addr rsp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer)
-{
- struct rt_sigframe *frame;
- Addr rsp =3D rsp_top_of_frame;
- Int sigNo =3D siginfo->si_signo;
-
- rsp -=3D sizeof(*frame);
- rsp =3D ROUNDDN(rsp, 16);
- frame =3D (struct rt_sigframe *)rsp;
-
- if (!extend(tst, rsp, sizeof(*frame)))
- return rsp_top_of_frame;
-
- /* retaddr, siginfo, uContext fields are to be written */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler =
frame",=20
- rsp, offsetof(struct rt_sigframe, vg) );
-
- if (flags & VKI_SA_RESTORER)
- frame->retaddr =3D (Addr)restorer;
- else
- frame->retaddr
- =3D VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
-
- VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
-
- /* SIGILL defines addr to be the faulting address */
- if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
- frame->sigInfo._sifields._sigfault._addr=20
- =3D (void*)tst->arch.vex.guest_RIP;
-
- synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fps=
tate);
-
- VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
- rsp, offsetof(struct rt_sigframe, vg) );
-
- build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
- =20
- return rsp;
-}
-
-
-void VGA_(push_signal_frame)(ThreadId tid, Addr rsp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer)
-{
- Addr rsp;
- struct rt_sigframe *frame;
- ThreadState* tst =3D VG_(get_ThreadState)(tid);
-
- rsp =3D build_rt_sigframe(tst, rsp_top_of_frame, siginfo,=20
- handler, flags, mask, restorer);
- frame =3D (struct rt_sigframe *)rsp;
-
- /* Set the thread so it will next run the handler. */
- /* tst->m_rsp =3D rsp; */
- SET_SIGNAL_RSP(tid, rsp);
-
- //VG_(printf)("handler =3D %p\n", handler);
- tst->arch.vex.guest_RIP =3D (Addr) handler;
- tst->arch.vex.guest_RDI =3D (ULong) siginfo->si_signo;
- tst->arch.vex.guest_RSI =3D (Addr) &frame->sigInfo;
- tst->arch.vex.guest_RDX =3D (Addr) &frame->uContext;
- /* This thread needs to be marked runnable, but we leave that the
- caller to do. */
-
- if (0)
- VG_(printf)("pushed signal frame; %%RSP now =3D %p, "
- "next %%RIP =3D %p, status=3D%d\n",=20
- rsp, tst->arch.vex.guest_RIP, tst->status);
-}
-
-
-/*------------------------------------------------------------*/
-/*--- Destroying signal frames ---*/
-/*------------------------------------------------------------*/
-
-/* Return False and don't do anything, just set the client to take a
- segfault, if it looks like the frame is corrupted. */
-static=20
-Bool restore_vg_sigframe ( ThreadState *tst,=20
- struct vg_sigframe *frame, Int *sigNo )
-{
- if (frame->magicPI !=3D 0x31415927 ||
- frame->magicE !=3D 0x27182818) {
- VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
- "corrupted. Killing process.",
- tst->tid);
- VG_(set_default_handler)(VKI_SIGSEGV);
- VG_(synth_fault)(tst->tid);
- *sigNo =3D VKI_SIGSEGV;
- return False;
- }
- tst->sig_mask =3D frame->mask;
- tst->tmp_sig_mask =3D frame->mask;
- tst->arch.vex_shadow =3D frame->vex_shadow;
- /* HACK ALERT */
- tst->arch.vex =3D frame->vex;
- /* end HACK ALERT */
- *sigNo =3D frame->sigNo_private;
- return True;
-}
-
-static=20
-void restore_sigcontext( ThreadState *tst,=20
- struct vki_sigcontext *sc,=20
- struct _vki_fpstate *fpstate )
-{
- tst->arch.vex.guest_RAX =3D sc->rax;
- tst->arch.vex.guest_RCX =3D sc->rcx;
- tst->arch.vex.guest_RDX =3D sc->rdx;
- tst->arch.vex.guest_RBX =3D sc->rbx;
- tst->arch.vex.guest_RBP =3D sc->rbp;=20
- tst->arch.vex.guest_RSP =3D sc->rsp;
- tst->arch.vex.guest_RSI =3D sc->rsi;
- tst->arch.vex.guest_RDI =3D sc->rdi;
- tst->arch.vex.guest_R8 =3D sc->r8;
- tst->arch.vex.guest_R9 =3D sc->r9;
- tst->arch.vex.guest_R10 =3D sc->r10;
- tst->arch.vex.guest_R11 =3D sc->r11;
- tst->arch.vex.guest_R12 =3D sc->r12;
- tst->arch.vex.guest_R13 =3D sc->r13;
- tst->arch.vex.guest_R14 =3D sc->r14;
- tst->arch.vex.guest_R15 =3D sc->r15;
-//:: tst->arch.vex.guest_rflags =3D sc->rflags;
-//:: tst->arch.vex.guest_RIP =3D sc->rip;
-
-//:: tst->arch.vex.guest_CS =3D sc->cs;=20
-//:: tst->arch.vex.guest_FS =3D sc->fs;
-//:: tst->arch.vex.guest_GS =3D sc->gs;
-
-//:: restore_i387(&tst->arch, fpstate);
-}
-
-
-static=20
-SizeT restore_rt_sigframe ( ThreadState *tst,=20
- struct rt_sigframe *frame, Int *sigNo )
-{
- if (restore_vg_sigframe(tst, &frame->vg, sigNo))
- restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpst=
ate);
-
- return sizeof(*frame);
-}
-
-
-void VGA_(signal_return)(ThreadId tid, Bool isRT)
-{
- Addr rsp;
- ThreadState* tst;
- SizeT size;
- Int sigNo;
-
- vg_assert(isRT);
-
- tst =3D VG_(get_ThreadState)(tid);
-
- /* Correctly reestablish the frame base address. */
- rsp =3D tst->arch.vex.guest_RSP;
-
- size =3D restore_rt_sigframe(tst, (struct rt_sigframe *)rsp, &sigNo);
-
- VG_TRACK( die_mem_stack_signal, rsp, size );
-
- if (VG_(clo_trace_signals))
- VG_(message)(
- Vg_DebugMsg,=20
- "VGA_(signal_return) (thread %d): isRT=3D%d valid magic; RIP=3D=
%p",=20
- tid, isRT, tst->arch.vex.guest_RIP);
-
- /* tell the tools */
- VG_TRACK( post_deliver_signal, tid, sigNo );
-}
-
-//:: /*------------------------------------------------------------*/
-//:: /*--- Making coredumps ---*/
-//:: /*------------------------------------------------------------*/
-//::=20
-//:: void VGA_(fill_elfregs_from_tst)(struct vki_user_regs_struct* regs,=
=20
-//:: const arch_thread_t* arch)
-//:: {
-//:: regs->rflags =3D arch->m_rflags;
-//:: regs->rsp =3D arch->m_rsp;
-//:: regs->rip =3D arch->m_rip;
-//::
-//:: regs->rbx =3D arch->m_rbx;
-//:: regs->rcx =3D arch->m_rcx;
-//:: regs->rdx =3D arch->m_rdx;
-//:: regs->rsi =3D arch->m_rsi;
-//:: regs->rdi =3D arch->m_rdi;
-//:: regs->rbp =3D arch->m_rbp;
-//:: regs->rax =3D arch->m_rax;
-//:: regs->r8 =3D arch->m_r8;
-//:: regs->r9 =3D arch->m_r9;
-//:: regs->r10 =3D arch->m_r10;
-//:: regs->r11 =3D arch->m_r11;
-//:: regs->r12 =3D arch->m_r12;
-//:: regs->r13 =3D arch->m_r13;
-//:: regs->r14 =3D arch->m_r14;
-//:: regs->r15 =3D arch->m_r15;
-//::=20
-//:: regs->cs =3D arch->m_cs;
-//:: regs->fs =3D arch->m_fs;
-//:: regs->gs =3D arch->m_gs;
-//:: }
-//::=20
-//:: static void fill_fpu(vki_elf_fpregset_t *fpu, const Char *from)
-//:: {
-//:: if (VG_(have_ssestate)) {
-//:: UShort *to;
-//:: Int i;
-//::=20
-//:: /* This is what the kernel does */
-//:: VG_(memcpy)(fpu, from, 7*sizeof(long));
-//:: =20
-//:: to =3D (UShort *)&fpu->st_space[0];
-//:: from +=3D 18 * sizeof(UShort);
-//::=20
-//:: for (i =3D 0; i < 8; i++, to +=3D 5, from +=3D 8)=20
-//:: VG_(memcpy)(to, from, 5*sizeof(UShort));
-//:: } else
-//:: VG_(memcpy)(fpu, from, sizeof(*fpu));
-//:: }
-//::=20
-//:: void VGA_(fill_elffpregs_from_tst)( vki_elf_fpregset_t* fpu,
-//:: const arch_thread_t* arch)
-//:: {
-//:: fill_fpu(fpu, (const Char *)&arch->m_sse);
-//:: }
-//::=20
-//:: void VGA_(fill_elffpxregs_from_tst) ( vki_elf_fpxregset_t* xfpu,
-//:: const arch_thread_t* arch )
-//:: {
-//:: VG_(memcpy)(xfpu, arch->m_sse.state, sizeof(*xfpu));
-//:: }
-//::=20
-//:: /*-----------------------------------------------------------------=
---*/
-//:: /*--- end =
---*/
-//:: /*-----------------------------------------------------------------=
---*/
Modified: trunk/coregrind/arm/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/arm/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/arm/Makefile.am 2005-04-24 14:18:14 UTC (rev 3556)
@@ -18,7 +18,6 @@
=20
libarch_a_SOURCES =3D \
dispatch.S \
- signals.c \
state.c
=20
if USE_PIE
Deleted: trunk/coregrind/arm/signals.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/arm/signals.c 2005-04-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/arm/signals.c 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1,312 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- Arch-specific signals stuff. arm/signals.c ---*/
-/*--------------------------------------------------------------------*/
-
-/*
- This file is part of Valgrind, a dynamic binary instrumentation
- framework.
-
- Copyright (C) 2000-2005 Nicholas Nethercote
- nj...@ca...
-
- 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 "libvex_guest_arm.h"
-
-/*------------------------------------------------------------*/
-/*--- Signal frame ---*/
-/*------------------------------------------------------------*/
-
-// A structure in which to save the application's registers
-// during the execution of signal handlers.
-
-#if 0
-typedef
- struct {
- /* There are two different stack frame formats, depending on
- whether the client set the SA_SIGINFO flag for the handler.
- This structure is put onto the client's stack as part of
- signal delivery, and therefore appears as the signal
- handler's arguments.
-
- The first two words are common for both frame formats -
- they're the return address and the signal number. */
-
- /* Sig handler's (bogus) return address */
- Addr retaddr;
- /* The arg to the sig handler. We need to inspect this after
- the handler returns, but it's unreasonable to assume that the
- handler won't change it. So we keep a second copy of it in
- sigNo_private. */
- Int sigNo;
-
- /* This is where the two frames start differing. */
- union {
- struct { /* set SA_SIGINFO */
- /* ptr to siginfo_t. */
- Addr psigInfo;
-
- /* ptr to ucontext */
- Addr puContext;
- } sigInfo;
- struct vki_sigcontext sigContext; /* did not set SA_SIGINFO */
- } handlerArgs;
-
- /* The rest are private fields which the handler is unaware of. */
-
- /* Sanity check word. */
- UInt magicPI;
- /* pointed to by psigInfo */
- vki_siginfo_t sigInfo;
- /* pointed to by puContext */
- struct vki_ucontext uContext;
-
- /* Safely-saved version of sigNo, as described above. */
- Int sigNo_private;
-
- /* Saved processor state. */
- VexGuestX86State vex;
- VexGuestX86State vex_shadow;
-
- /* saved signal mask to be restored when handler returns */
- vki_sigset_t mask;
-
- /* Scheduler-private stuff: what was the thread's status prior to
- delivering this signal? */
- ThreadStatus status;
- void* /*pthread_mutex_t* */ associated_mx;
- void* /*pthread_cond_t* */ associated_cv;
-
- /* Sanity check word. Is the highest-addressed word; do not
- move!*/
- UInt magicE;
- }
- VgSigFrame;
-#endif
-
-/*------------------------------------------------------------*/
-/*--- Signal operations ---*/
-/*------------------------------------------------------------*/
-
-#if 0
-/* Make up a plausible-looking thread state from the thread's current st=
ate */
-static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
- const vki_sigset_t *set, struct vki_ucontext *uc)
-{
- ThreadState *tst =3D VG_(get_ThreadState)(tid);
- struct vki_sigcontext *sc =3D &uc->uc_mcontext;
-
- VG_(memset)(uc, 0, sizeof(*uc));
-
- uc->uc_flags =3D 0;
- uc->uc_link =3D 0;
- uc->uc_sigmask =3D *set;
- uc->uc_stack =3D tst->altstack;
-
-#define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
- SC2(gs,GS);
- SC2(fs,FS);
- SC2(es,ES);
- SC2(ds,DS);
-
- SC2(edi,EDI);
- SC2(esi,ESI);
- SC2(ebp,EBP);
- SC2(esp,ESP);
- SC2(ebx,EBX);
- SC2(edx,EDX);
- SC2(ecx,ECX);
- SC2(eax,EAX);
-
- SC2(eip,EIP);
- SC2(cs,CS);
- sc->eflags =3D LibVEX_GuestX86_get_eflags(&tst->arch.vex);
- SC2(ss,SS);
- /* XXX esp_at_signal */
- /* XXX trapno */
- /* XXX err */
-#undef SC2
-
- sc->cr2 =3D (UInt)si->_sifields._sigfault._addr;
-}
-#endif
-
-#if 0
-#define SET_SIGNAL_ESP(zztid, zzval) \
- SET_THREAD_REG(zztid, zzval, VGA_STACK_PTR, VGA_R_STACK_PTR, \
- post_reg_write_deliver_signal)
-#endif
-
-void VGA_(push_signal_frame)(ThreadId tid, Addr esp_top_of_frame,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask)
-{
- I_die_here;
-#if 0
- Addr esp;
- ThreadState* tst;
- VgSigFrame* frame;
- Int sigNo =3D siginfo->si_signo;
-
- esp =3D esp_top_of_frame;
- esp -=3D sizeof(VgSigFrame);
- frame =3D (VgSigFrame*)esp;
-
- tst =3D & VG_(threads)[tid];
-
- /* For tracking memory events, indicate the entire frame has been
- * allocated, but pretend that only the first four words are written =
*/
- VG_TRACK( new_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
-
- /* Assert that the frame is placed correctly. */
- vg_assert( (sizeof(VgSigFrame) & 0x3) =3D=3D 0 );
- vg_assert( ((Char*)(&frame->magicE)) + sizeof(UInt)=20
- =3D=3D ((Char*)(esp_top_of_frame)) );
-
- /* retaddr, sigNo, psigInfo, puContext fields are to be written */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",=20
- (Addr)frame, offsetof(VgSigFrame, handlerArg=
s) );
- frame->retaddr =3D (UInt)VG_(client_trampoline_code)+VG_(tramp_sig=
return_offset);
- frame->sigNo =3D sigNo;
- frame->sigNo_private =3D sigNo;
- VG_TRACK( post_mem_write, (Addr)frame, offsetof(VgSigFrame, handlerAr=
gs) );
-
- if (flags & VKI_SA_SIGINFO) {
- /* if the client asked for a siginfo delivery, then build the stac=
k that way */
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
- frame->handlerArgs.sigInfo.psigInfo =3D (Addr)&frame->sigInfo;
- frame->handlerArgs.sigInfo.puContext =3D (Addr)&frame->uContext;
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame-=
>handlerArgs.sigInfo) );
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
- VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
- VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sig=
Info) );
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(siginfo)",=20
- (Addr)&frame->uContext, sizeof(frame->uContext) );
- synth_ucontext(tid, siginfo, mask, &frame->uContext);
- VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uC=
ontext) );
- } else {
- struct vki_ucontext uc;
-
- /* otherwise just put the sigcontext there */
-
- synth_ucontext(tid, siginfo, mask, &uc);
-
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame=
(sigcontext)",=20
- (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigContext) );
- VG_(memcpy)(&frame->handlerArgs.sigContext, &uc.uc_mcontext,=20
- sizeof(struct vki_sigcontext));
- VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs,=20
- sizeof(frame->handlerArgs.sigContext) );
- =20
- frame->handlerArgs.sigContext.oldmask =3D tst->sig_mask.sig[0];
- }
-
- frame->magicPI =3D 0x31415927;
-
- frame->vex =3D tst->arch.vex;
- if (VG_(needs).shadow_regs)
- frame->vex_shadow =3D tst->arch.vex_shadow;
-
- frame->mask =3D tst->sig_mask;
-
- /* If the thread is currently blocked in a syscall, we want it to
- resume as runnable. */
- if (tst->status =3D=3D VgTs_WaitSys)
- frame->status =3D VgTs_Runnable;
- else
- frame->status =3D tst->status;
-=20
- frame->associated_mx =3D tst->associated_mx;
- frame->associated_cv =3D tst->associated_cv;
-
- frame->magicE =3D 0x27182818;
-
- /* Ensure 'tid' and 'tst' correspond */
- vg_assert(& VG_(threads)[tid] =3D=3D tst);
- /* Set the thread so it will next run the handler. */
- /* tst->m_esp =3D esp; */
- SET_SIGNAL_ESP(tid, esp);
-
- tst->arch.vex.guest_EIP =3D (Addr) handler;
- /* This thread needs to be marked runnable, but we leave that the
- caller to do. */
-
- if (0)
- VG_(printf)("pushed signal frame; %%ESP now =3D %p, next %%EBP =3D=
%p, status=3D%d\n",=20
- esp, tst->arch.vex.guest_EIP, tst->status);
-#endif
-}
-
-Int VGA_(pop_signal_frame)(ThreadId tid)
-{
- I_die_here;
-#if 0
- Addr esp;
- VgSigFrame* frame;
- ThreadState* tst;
-
- vg_assert(VG_(is_valid_tid)(tid));
- tst =3D & VG_(threads)[tid];
-
- /* Correctly reestablish the frame base address. */
- esp =3D tst->arch.vex.guest_ESP;
- frame =3D (VgSigFrame*)
- (esp -4 /* because the handler's RET pops the RA */
- +20 /* because signalreturn_bogusRA pushes 5 words */)=
;
-
- vg_assert(frame->magicPI =3D=3D 0x31415927);
- vg_assert(frame->magicE =3D=3D 0x27182818);
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg,=20
- "vg_pop_signal_frame (thread %d): valid magic; EIP=3D%p", tid, =
frame->vex.guest_EIP);
-
- /* Mark the frame structure as nonaccessible. */
- VG_TRACK( die_mem_stack_signal, (Addr)frame, sizeof(VgSigFrame) );
-
- /* restore machine state */
- tst->arch.vex =3D frame->vex;
- if (VG_(needs).shadow_regs)
- tst->arch.vex_shadow =3D frame->vex_shadow;
-
- /* And restore the thread's status to what it was before the signal
- was delivered. */
- tst->status =3D frame->status;
-
- tst->associated_mx =3D frame->associated_mx;
- tst->associated_cv =3D frame->associated_cv;
-
- tst->sig_mask =3D frame->mask;
-
- /* don't use the copy exposed to the handler; it might have changed
- it. */
- return frame->sigNo_private;=20
-#endif
-}
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
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-24 12:33:12 UTC (rev 3555)
+++ trunk/coregrind/core.h 2005-04-24 14:18:14 UTC (rev 3556)
@@ -1687,13 +1687,6 @@
// Used by leakcheck
extern void VGA_(mark_from_registers)(ThreadId tid, void (*marker)(Addr)=
);
=20
-// Signal stuff
-extern void VGA_(push_signal_frame) ( ThreadId tid, Addr sp_top_of_frame=
,
- const vki_siginfo_t *siginfo,
- void *handler, UInt flags,
- const vki_sigset_t *mask,
- void *restorer );
-
////typedef struct _ThreadArchAux ThreadArchAux;
=20
=20
Added: trunk/coregrind/m_sigframe/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/m_sigframe/Makefile.am 2005-04-24 12:33:12 UTC (rev 3=
555)
+++ trunk/coregrind/m_sigframe/Makefile.am 2005-04-24 14:18:14 UTC (rev 3=
556)
@@ -0,0 +1,18 @@
+include $(top_srcdir)/Makefile.all.am
+include $(top_srcdir)/Makefile.core-AM_CPPFLAGS.am
+
+AM_CFLAGS =3D $(WERROR) -Wmissing-prototypes -Winline -Wall -Wshadow -O =
-g
+
+EXTRA_DIST =3D \
+ README_SIGFRAME.txt
+
+noinst_LIBRARIES =3D libsigframe.a
+
+libsigframe_a_SOURCES =3D \
+ sigframe-@VG_PLATFORM@.c
+
+if USE_PIE
+libsigframe_a_CFLAGS =3D $(AM_CFLAGS) -fpie
+else
+libsigframe_a_CFLAGS =3D $(AM_CFLAGS)
+endif
Copied: trunk/coregrind/m_sigframe/sigframe-amd64-linux.c (from rev 3550,=
trunk/coregrind/amd64/signals.c)
Copied: trunk/coregrind/m_sigframe/sigframe-arm-linux.c (from rev 3550, t=
runk/coregrind/arm/signals.c)
Copied: trunk/coregrind/m_sigframe/sigframe-x86-linux.c (from rev 3550, t=
runk/coregrind/x86/signals.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/x86/signals.c 2005-04-24 00:21:01 UTC (rev 3550)
+++ trunk/coregrind/m_sigframe/sigframe-x86-linux.c 2005-04-24 14:18:14 U=
TC (rev 3556)
@@ -0,0 +1,753 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Create/destroy signal delivery frames. ---*/
+/*--- sigframe-x86-linux.c ---*/
+/*--------------------------------------------------------------------*/
+
+/*
+ This file is part of Valgrind, a dynamic binary instrumentation
+ framework.
+
+ Copyright (C) 2000-2005 Nicholas Nethercote
+ nj...@ca...
+
+ 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_sigframe.h"
+#include "libvex_guest_x86.h"
+
+
+/* This module creates and removes signal frames for signal deliveries
+ on x86-linux.
+
+ Note, this file contains kernel-specific knowledge in the form of
+ 'struct sigframe' and 'struct rt_sigframe'. How does that relate
+ to the vki kernel interface stuff?
+
+ Either a 'struct sigframe' or a 'struct rtsigframe' is pushed=20
+ onto the client's stack. This contains a subsidiary
+ vki_ucontext. That holds the vcpu's state across the signal,=20
+ so that the sighandler can mess with the vcpu state if it
+ really wants.
+
+ FIXME: sigcontexting is basically broken for the moment. When
+ delivering a signal, the integer registers and %eflags are
+ correctly written into the sigcontext, however the FP and SSE state
+ is not. When returning from a signal, only the integer registers
+ are restored from the sigcontext; the rest of the CPU state is
+ restored to what it was before the signal.
+
+ This will be fixed.
+*/
+
+
+/*------------------------------------------------------------*/
+/*--- Signal frame layouts ---*/
+/*------------------------------------------------------------*/
+
+// A structure in which to save the application's registers
+// during the execution of signal handlers.
+
+// Linux has 2 signal frame structures: one for normal signal
+// deliveries, and one for SA_SIGINFO deliveries (also known as RT
+// signals).
+//
+// In theory, so long as we get the arguments to the handler function
+// right, it doesn't matter what the exact layout of the rest of the
+// frame is. Unfortunately, things like gcc's exception unwinding
+// make assumptions about the locations of various parts of the frame,
+// so we need to duplicate it exactly.
+
+/* Valgrind-specific parts of the signal frame */
+struct vg_sigframe
+{
+ /* Sanity check word. */
+ UInt magicPI;
+
+ UInt handlerflags; /* flags for signal handler */
+
+
+ /* Safely-saved version of sigNo, as described above. */
+ Int sigNo_private;
+
+ /* XXX This is wrong. Surely we should store the shadow values
+ into the shadow memory behind the actual values? */
+ VexGuestX86State vex_shadow;
+
+ /* HACK ALERT */
+ VexGuestX86State vex;
+ /* end HACK ALERT */
+
+ /* saved signal mask to be restored when handler returns */
+ vki_sigset_t mask;
+
+ /* Sanity check word. Is the highest-addressed word; do not
+ move!*/
+ UInt magicE;
+};
+
+struct sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ struct vki_sigcontext sigContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
+
+struct rt_sigframe
+{
+ /* Sig handler's return address */
+ Addr retaddr;
+ Int sigNo;
+
+ /* ptr to siginfo_t. */
+ Addr psigInfo;
+
+ /* ptr to ucontext */
+ Addr puContext;
+ /* pointed to by psigInfo */
+ vki_siginfo_t sigInfo;
+
+ /* pointed to by puContext */
+ struct vki_ucontext uContext;
+ struct _vki_fpstate fpstate;
+
+ struct vg_sigframe vg;
+};
+
+
+//:: /*------------------------------------------------------------*/
+//:: /*--- Signal operations ---*/
+//:: /*------------------------------------------------------------*/
+//::=20
+//:: /*=20
+//:: Great gobs of FP state conversion taken wholesale from
+//:: linux/arch/i386/kernel/i387.c
+//:: */
+//::=20
+//:: /*
+//:: * FXSR floating point environment conversions.
+//:: */
+//:: #define X86_FXSR_MAGIC 0x0000
+//::=20
+//:: /*
+//:: * FPU tag word conversions.
+//:: */
+//::=20
+//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
+//:: {
+//:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
+//:: =20
+//:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
+//:: tmp =3D ~twd;
+//:: tmp =3D (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
+//:: /* and move the valid bits to the lower byte. */
+//:: tmp =3D (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
+//:: tmp =3D (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
+//:: tmp =3D (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
+//:: return tmp;
+//:: }
+//::=20
+//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_str=
uct *fxsave )
+//:: {
+//:: struct _vki_fpxreg *st =3D NULL;
+//:: unsigned long twd =3D (unsigned long) fxsave->twd;
+//:: unsigned long tag;
+//:: unsigned long ret =3D 0xffff0000u;
+//:: int i;
+//::=20
+//:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
+//::=20
+//:: for ( i =3D 0 ; i < 8 ; i++ ) {
+//:: if ( twd & 0x1 ) {
+//:: st =3D (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
+//::=20
+//:: switch ( st->exponent & 0x7fff ) {
+//:: case 0x7fff:
+//:: tag =3D 2; /* Special */
+//:: break;
+//:: case 0x0000:
+//:: if ( !st->significand[0] &&
+//:: !st->significand[1] &&
+//:: !st->significand[2] &&
+//:: !st->significand[3] ) {
+//:: tag =3D 1; /* Zero */
+//:: } else {
+//:: tag =3D 2; /* Special */
+//:: }
+//:: break;
+//:: default:
+//:: if ( st->significand[3] & 0x8000 ) {
+//:: tag =3D 0; /* Valid */
+//:: } else {
+//:: tag =3D 2; /* Special */
+//:: }
+//:: break;
+//:: }
+//:: } else {
+//:: tag =3D 3; /* Empty */
+//:: }
+//:: ret |=3D (tag << (2 * i));
+//:: twd =3D twd >> 1;
+//:: }
+//:: return ret;
+//:: }
+//::=20
+//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
+//:: const struct i387_fxsave_struct *fxsave )
+//:: {
+//:: unsigned long env[7];
+//:: struct _vki_fpreg *to;
+//:: struct _vki_fpxreg *from;
+//:: int i;
+//::=20
+//:: env[0] =3D (unsigned long)fxsave->cwd | 0xffff0000ul;
+//:: env[1] =3D (unsigned long)fxsave->swd | 0xffff0000ul;
+//:: env[2] =3D twd_fxsr_to_i387(fxsave);
+//:: env[3] =3D fxsave->fip;
+//:: env[4] =3D fxsave->fcs | ((unsigned long)fxsave->fop << 16);
+//:: env[5] =3D fxsave->foo;
+//:: env[6] =3D fxsave->fos;
+//:: =20
+//:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
+//::=20
+//:: to =3D &buf->_st[0];
+//:: from =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
+//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
+//:: unsigned long __user *t =3D (unsigned long __user *)to;
+//:: unsigned long *f =3D (unsigned long *)from;
+//::=20
+//:: t[0] =3D f[0];
+//:: t[1] =3D f[1];
+//:: to->exponent =3D from->exponent;
+//:: }
+//:: }
+//::=20
+//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsa=
ve,
+//:: const struct _vki_fpstate *buf )
+//:: {
+//:: unsigned long env[7];
+//:: struct _vki_fpxreg *to;
+//:: const struct _vki_fpreg *from;
+//:: int i;
+//:: =09
+//:: VG_(memcpy)(env, buf, 7 * sizeof(long));
+//::=20
+//:: fxsave->cwd =3D (unsigned short)(env[0] & 0xffff);
+//:: fxsave->swd =3D (unsigned short)(env[1] & 0xffff);
+//:: fxsave->twd =3D twd_i387_to_fxsr((unsigned short)(env[2] & 0xfff=
f));
+//:: fxsave->fip =3D env[3];
+//:: fxsave->fop =3D (unsigned short)((env[4] & 0xffff0000ul) >> 16);
+//:: fxsave->fcs =3D (env[4] & 0xffff);
+//:: fxsave->foo =3D env[5];
+//:: fxsave->fos =3D env[6];
+//::=20
+//:: to =3D (struct _vki_fpxreg *) &fxsave->st_space[0];
+//:: from =3D &buf->_st[0];
+//:: for ( i =3D 0 ; i < 8 ; i++, to++, from++ ) {
+//:: unsigned long *t =3D (unsigned long *)to;
+//:: unsigned long __user *f =3D (unsigned long __user *)from;
+//::=20
+//:: t[0] =3D f[0];
+//:: t[1] =3D f[1];
+//:: to->exponent =3D from->exponent;
+//:: }
+//:: }
+//::=20
+//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vk=
i_fpstate *buf )
+//:: {
+//:: struct i387_fsave_struct *fs =3D ®s->m_sse.fsave;
+//::=20
+//:: fs->status =3D fs->swd;
+//:: VG_(memcpy)(buf, fs, sizeof(*fs));
+//:: }
+//::=20
+//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpst=
ate *buf )
+//:: {
+//:: const struct i387_fxsave_struct *fx =3D ®s->m_sse.fxsave;
+//:: convert_fxsr_to_user( buf, fx );
+//::=20
+//:: buf->status =3D fx->swd;
+//:: buf->magic =3D X86_FXSR_MAGIC;
+//:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct=
));
+//:: }
+//::=20
+//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *bu=
f )
+//:: {
+//:: if ( VG_(have_ssestate) )
+//:: save_i387_fxsave( regs, buf );
+//:: else
+//:: save_i387_fsave( regs, buf );
+//:: }
+//::=20
+//:: static inline void restore_i387_fsave( arch_thread_t *regs, const s=
truct _vki_fpstate __user *buf )
+//:: {
+//:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_s=
truct) );
+//:: }
+//::=20
+//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct =
_vki_fpstate __user *buf )
+//:: {
+//:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],=20
+//:: sizeof(struct i387_fxsave_struct) );
+//:: /* mxcsr reserved bits must be masked to zero for security reaso=
ns */
+//:: regs->m_sse.fxsave.mxcsr &=3D 0xffbf;
+//:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
+//:: }
+//::=20
+//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fp=
state __user *buf )
+//:: {
+//:: if ( VG_(have_ssestate) ) {
+//:: restore_i387_fxsave( regs, buf );
+//:: } else {
+//:: restore_i387_fsave( regs, buf );
+//:: }
+//:: }
+
+
+/*------------------------------------------------------------*/
+/*--- Creating signal frames ---*/
+/*------------------------------------------------------------*/
+
+/* Create a plausible-looking sigcontext from the thread's
+ Vex guest state. NOTE: does not fill in the FP or SSE
+ bits of sigcontext at the moment.
+*/
+static=20
+void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,=20
+ const vki_sigset_t *set,=20
+ struct vki_ucontext *uc, struct _vki_fpstate *fpstat=
e)
+{
+ ThreadState *tst =3D VG_(get_ThreadState)(tid);
+ struct vki_sigcontext *sc =3D &uc->uc_mcontext;
+
+ VG_(memset)(uc, 0, sizeof(*uc));
+
+ uc->uc_flags =3D 0;
+ uc->uc_link =3D 0;
+ uc->uc_sigmask =3D *set;
+ uc->uc_stack =3D tst->altstack;
+ sc->fpstate =3D fpstate;
+
+ // FIXME: save_i387(&tst->arch, fpstate);
+
+# define SC2(reg,REG) sc->reg =3D tst->arch.vex.guest_##REG
+ SC2(gs,GS);
+ SC2(fs,FS);
+ SC2(es,ES);
+ SC2(ds,DS);
+
+ SC2(edi,EDI);
+ SC2(esi,ESI);
+ SC2(ebp,EBP);
+ SC2(esp,ESP);
+ SC2(ebx,EBX);
+ SC2(edx,EDX);
+ SC2(ecx,ECX);
+ SC2(eax,EAX);
+
+ SC2(eip,EIP);
+ SC2(cs,CS);
+ sc->eflags =3D LibVEX_GuestX86_get_eflags(&tst->arch.vex);
+ SC2(ss,SS);
+ /* XXX esp_at_signal */
+ /* XXX trapno */
+ /* XXX err */
+# undef SC2
+
+ sc->cr2 =3D (UInt)si->_sifields._sigfault._addr;
+}
+
+
+#define SET_SIGNAL_ESP(zztid, zzval) \
+ SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
+ Vg_CoreSignal, zztid, O_STACK_PTR, sizeof(Addr))
+
+
+/* Extend the stack segment downwards if needed so as to ensure the
+ new signal frames are mapped to something. Return a Bool
+ indicating whether or not the operation was successful.
+*/
+static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
+{
+ ThreadId tid =3D tst->tid;
+ Segment *stackseg =3D NULL;
+
+ if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
+ stackseg =3D VG_(find_segment)(addr);
+ if (0 && stackseg)
+ VG_(printf)("frame=3D%p seg=3D%p-%p\n",
+ addr, stackseg->addr, stackseg->addr+stackseg->len);
+ }
+
+ if (stackseg =3D=3D NULL=20
+ || (stackseg->prot & (VKI_PROT_READ|VKI_PROT_WRITE)) =3D=3D 0) {
+ VG_(message)(
+ Vg_UserMsg,
+ "Can't extend stack to %p during signal delivery for thread %d:=
",
+ addr, tid);
+ if (stackseg =3D=3D NULL)
+ VG_(message)(Vg_UserMsg, " no stack segment");
+ else
+ VG_(message)(Vg_UserMsg, " too small or bad protection modes")=
;
+
+ /* set SIGSEGV to default handler */
+ VG_(set_default_handler)(VKI_SIGSEGV);
+ VG_(synth_fault_mapping)(tid, addr);
+
+ /* The whole process should be about to die, since the default
+ action of SIGSEGV to kill the whole process. */
+ return False;
+ }
+
+ /* For tracking memory events, indicate the entire frame has been
+ allocated. */
+ VG_TRACK( new_mem_stack_signal, addr, size );
+
+ return True;
+}
+
+
+/* Build the Valgrind-specific part of a signal frame. */
+
+static void build_vg_sigframe(struct vg_sigframe *frame,
+ ThreadState *tst,
+ const vki_sigset_t *mask,
+ UInt flags,
+ Int sigNo)
+{
+ frame->sigNo_private =3D sigNo;
+ frame->magicPI =3D 0x31415927;
+ frame->vex_shadow =3D tst->arch.vex_shadow;
+ /* HACK ALERT */
+ frame->vex =3D tst->arch.vex;
+ /* end HACK ALERT */
+ frame->mask =3D tst->sig_mask;
+ frame->handlerflags =3D flags;
+ frame->magicE =3D 0x27182818;
+}
+
+
+static Addr build_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct sigframe *frame;
+ Addr esp =3D esp_top_of_frame;
+ Int sigNo =3D siginfo->si_signo;
+ struct vki_ucontext uc;
+
+ vg_assert((flags & VKI_SA_SIGINFO) =3D=3D 0);
+
+ esp -=3D sizeof(*frame);
+ esp =3D ROUNDDN(esp, 16);
+ frame =3D (struct sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, siguContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler fra=
me",=20
+ esp, offsetof(struct sigframe, vg) );
+
+ frame->sigNo =3D sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr =3D (Addr)restorer;
+ else
+ frame->retaddr
+ =3D VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
+
+ synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
+
+ VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,=20
+ sizeof(struct vki_sigcontext));
+ frame->sigContext.oldmask =3D mask->sig[0];
+
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
+ esp, offsetof(struct sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+ =20
+ return esp;
+}
+
+
+static Addr build_rt_sigframe(ThreadState *tst,
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler, UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer)
+{
+ struct rt_sigframe *frame;
+ Addr esp =3D esp_top_of_frame;
+ Int sigNo =3D siginfo->si_signo;
+
+ vg_assert((flags & VKI_SA_SIGINFO) !=3D 0);
+
+ esp -=3D sizeof(*frame);
+ esp =3D ROUNDDN(esp, 16);
+ frame =3D (struct rt_sigframe *)esp;
+
+ if (!extend(tst, esp, sizeof(*frame)))
+ return esp_top_of_frame;
+
+ /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler =
frame",=20
+ esp, offsetof(struct rt_sigframe, vg) );
+
+ frame->sigNo =3D sigNo;
+
+ if (flags & VKI_SA_RESTORER)
+ frame->retaddr =3D (Addr)restorer;
+ else
+ frame->retaddr=20
+ =3D VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
+
+ frame->psigInfo =3D (Addr)&frame->sigInfo;
+ frame->puContext =3D (Addr)&frame->uContext;
+ VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
+
+ /* SIGILL defines addr to be the faulting address */
+ if (sigNo =3D=3D VKI_SIGILL && siginfo->si_code > 0)
+ frame->sigInfo._sifields._sigfault._addr=20
+ =3D (void*)tst->arch.vex.guest_EIP;
+
+ synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fps=
tate);
+
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,=20
+ esp, offsetof(struct rt_sigframe, vg) );
+
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+ =20
+ return esp;
+}
+
+
+/* EXPORTED */
+void VG_(sigframe_create)( ThreadId tid,=20
+ Addr esp_top_of_frame,
+ const vki_siginfo_t *siginfo,
+ void *handler,=20
+ UInt flags,
+ const vki_sigset_t *mask,
+ void *restorer )
+{
+ Addr esp;
+ ThreadState* tst =3D VG_(get_ThreadState)(tid);
+
+ if (flags & VKI_SA_SIGINFO)
+ esp =3D build_rt_sigframe(tst, esp_top_of_frame, siginfo,=20
+ handler, flags, mask, restorer);
+ else
+ esp =3D build_sigframe(tst, esp_top_of_frame,=20
+ siginfo, handler, flags, mask, restorer)=
;
+
+ /* Set the thread so it will next run the handler. */
+ /* tst->m_esp =3D esp; */
+ SET_SIGNAL_ESP(tid, esp);
+
+ //VG_(printf)("handler =3D %p\n", handler);
+ tst->arch.vex.guest_EIP =3D (Addr) handler;
+ /* This thread needs to be marked runnable, but we leave that the
+ caller to do. */
+
+ if (0)
+ VG_(printf)("pushed signal frame; %%ESP now =3D %p, "
+ "next %%EIP =3D %p, status=3D%d\n",=20
+ esp, tst->arch.vex.guest_EIP, tst->status);
+}
+
+
+/*------------------------------------------------------------...
[truncated message content] |
|
From: <sv...@va...> - 2005-04-24 12:33:30
|
Author: sewardj
Date: 2005-04-24 13:33:12 +0100 (Sun, 24 Apr 2005)
New Revision: 3555
Added:
trunk/coregrind/m_errormgr.c
trunk/coregrind/m_execontext.c
trunk/coregrind/m_stacktrace.c
Removed:
trunk/coregrind/errormgr.c
trunk/coregrind/execontext.c
trunk/coregrind/stacktrace.c
Modified:
trunk/coregrind/Makefile.am
Log:
Rename the first three modules as per naming scheme.
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-24 12:19:13 UTC (rev 3554)
+++ trunk/coregrind/Makefile.am 2005-04-24 12:33:12 UTC (rev 3555)
@@ -52,9 +52,9 @@
valgrind_LDADD=3D
=20
stage2_SOURCES =3D \
- errormgr.c \
- execontext.c \
- stacktrace.c \
+ m_errormgr.c \
+ m_execontext.c \
+ m_stacktrace.c \
ume.c \
\
vg_scheduler.c \
Deleted: 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-24 12:19:13 UTC (rev 3554)
+++ trunk/coregrind/errormgr.c 2005-04-24 12:33:12 UTC (rev 3555)
@@ -1,1031 +0,0 @@
-
-/*--------------------------------------------------------------------*/
-/*--- 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 ---*/
-/*--------------------------------------------------------------------*/
Deleted: trunk/coregrind/execontext.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/execontext.c 2005-04-24 12:19:13 UTC (rev 3554)
+++ trunk/coregrind/execontext.c 2005-04-24 12:33:12 UTC (rev 3555)
@@ -1,256 +0,0 @@
-/*--------------------------------------------------------------------*/
-/*--- execontext.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"
-
-/*------------------------------------------------------------*/
-/*--- Low-level ExeContext storage. ---*/
-/*------------------------------------------------------------*/
-
-/* The first 4 IP values are used in comparisons do remove duplicate err=
ors,
- and for comparing against suppression specifications. The rest are
- purely informational (but often important). */
-
-struct _ExeContext {
- struct _ExeContext * next;
- /* Variable-length array. The size is VG_(clo_backtrace_size); at
- least 1, at most VG_DEEPEST_BACKTRACE. [0] is the current IP,
- [1] is its caller, [2] is the caller of [1], etc. */
- Addr ips[0];
-};
-
-/* Number of lists in which we keep track of ExeContexts. Should be
- prime. */
-#define N_EC_LISTS 4999 /* a prime number */
-
-/* The idea is only to ever store any one context once, so as to save
- space and make exact comparisons faster. */
-
-static ExeContext* ec_list[N_EC_LISTS];
-
-/* Stats only: the number of times the system was searched to locate a
- context. */
-static UInt ec_searchreqs;
-
-/* Stats only: the number of full context comparisons done. */
-static UInt ec_searchcmps;
-
-/* Stats only: total number of stored contexts. */
-static UInt ec_totstored;
-
-/* Number of 2, 4 and (fast) full cmps done. */
-static UInt ec_cmp2s;
-static UInt ec_cmp4s;
-static UInt ec_cmpAlls;
-
-
-/*------------------------------------------------------------*/
-/*--- Exported functions. ---*/
-/*------------------------------------------------------------*/
-
-
-/* Initialise this subsystem. */
-static void init_ExeContext_storage ( void )
-{
- Int i;
- static Bool init_done =3D False;
- if (init_done)
- return;
- ec_searchreqs =3D 0;
- ec_searchcmps =3D 0;
- ec_totstored =3D 0;
- ec_cmp2s =3D 0;
- ec_cmp4s =3D 0;
- ec_cmpAlls =3D 0;
- for (i =3D 0; i < N_EC_LISTS; i++)
- ec_list[i] =3D NULL;
- init_done =3D True;
-}
-
-
-/* Print stats. */
-void VG_(print_ExeContext_stats) ( void )
-{
- init_ExeContext_storage();
- VG_(message)(Vg_DebugMsg,=20
- " exectx: %d lists, %d contexts (avg %d per list)",
- N_EC_LISTS, ec_totstored,=20
- ec_totstored / N_EC_LISTS=20
- );
- VG_(message)(Vg_DebugMsg,=20
- " exectx: %d searches, %d full compares (%d per 1000)",
- ec_searchreqs, ec_searchcmps,=20
- ec_searchreqs =3D=3D 0=20
- ? 0=20
- : (UInt)( (((ULong)ec_searchcmps) * 1000)=20
- / ((ULong)ec_searchreqs ))=20
- );
- VG_(message)(Vg_DebugMsg,=20
- " exectx: %d cmp2, %d cmp4, %d cmpAll",
- ec_cmp2s, ec_cmp4s, ec_cmpAlls=20
- );
-}
-
-
-/* Print an ExeContext. */
-void VG_(pp_ExeContext) ( ExeContext* ec )
-{
- VG_(pp_StackTrace)( ec->ips, VG_(clo_backtrace_size) );
-}
-
-
-/* Compare two ExeContexts, comparing all callers. */
-Bool VG_(eq_ExeContext) ( VgRes res, ExeContext* e1, ExeContext* e2 )
-{
- if (e1 =3D=3D NULL || e2 =3D=3D NULL)=20
- return False;
- switch (res) {
- case Vg_LowRes:
- /* Just compare the top two callers. */
- ec_cmp2s++;
- if (e1->ips[0] !=3D e2->ips[0]) return False;
-
- if (VG_(clo_backtrace_size) < 2) return True;
- if (e1->ips[1] !=3D e2->ips[1]) return False;
- return True;
-
- case Vg_MedRes:
- /* Just compare the top four callers. */
- ec_cmp4s++;
- if (e1->ips[0] !=3D e2->ips[0]) return False;
-
- if (VG_(clo_backtrace_size) < 2) return True;
- if (e1->ips[1] !=3D e2->ips[1]) return False;
-
- if (VG_(clo_backtrace_size) < 3) return True;
- if (e1->ips[2] !=3D e2->ips[2]) return False;
-
- if (VG_(clo_backtrace_size) < 4) return True;
- if (e1->ips[3] !=3D e2->ips[3]) return False;
- return True;
-
- case Vg_HighRes:
- ec_cmpAlls++;
- /* Compare them all -- just do pointer comparison. */
- if (e1 !=3D e2) return False;
- return True;
-
- default:
- VG_(core_panic)("VG_(eq_ExeContext): unrecognised VgRes");
- }
-}
-
-/* This guy is the head honcho here. Take a snapshot of the client's
- stack. Search our collection of ExeContexts to see if we already
- have it, and if not, allocate a new one. Either way, return a
- pointer to the context. If there is a matching context we
- guarantee to not allocate a new one. Thus we never store
- duplicates, and so exact equality can be quickly done as equality
- on the returned ExeContext* values themselves. Inspired by Hugs's
- Text type. =20
-*/
-ExeContext* VG_(record_ExeContext) ( ThreadId tid )
-{
- Int i;
- Addr ips[VG_DEEPEST_BACKTRACE];
- Bool same;
- UWord hash;
- ExeContext* new_ec;
- ExeContext* list;
-
- VGP_PUSHCC(VgpExeContext);
-
- init_ExeContext_storage();
- vg_assert(VG_(clo_backtrace_size) >=3D 1=20
- && VG_(clo_backtrace_size) <=3D VG_DEEPEST_BACKTRACE);
-
- VG_(get_StackTrace)( tid, ips, VG_(clo_backtrace_size) );
-
- /* Now figure out if we've seen this one before. First hash it so
- as to determine the list number. */
-
- hash =3D 0;
- for (i =3D 0; i < VG_(clo_backtrace_size); i++) {
- hash ^=3D ips[i];
- hash =3D (hash << 29) | (hash >> 3);
- }
- hash =3D hash % N_EC_LISTS;
-
- /* And (the expensive bit) look a matching entry in the list. */
-
- ec_searchreqs++;
-
- list =3D ec_list[hash];
-
- while (True) {
- if (list =3D=3D NULL) break;
- ec_searchcmps++;
- same =3D True;
- for (i =3D 0; i < VG_(clo_backtrace_size); i++) {
- if (list->ips[i] !=3D ips[i]) {
- same =3D False;
- break;=20
- }
- }
- if (same) break;
- list =3D list->next;
- }
-
- if (list !=3D NULL) {
- /* Yay! We found it. */
- VGP_POPCC(VgpExeContext);
- return list;
- }
-
- /* Bummer. We have to allocate a new context record. */
- ec_totstored++;
-
- new_ec =3D VG_(arena_malloc)( VG_AR_EXECTXT,=20
- sizeof(struct _ExeContext *)=20
- + VG_(clo_backtrace_size) * sizeof(Addr) =
);
-
- for (i =3D 0; i < VG_(clo_backtrace_size); i++)
- new_ec->ips[i] =3D ips[i];
-
- new_ec->next =3D ec_list[hash];
- ec_list[hash] =3D new_ec;
-
- VGP_POPCC(VgpExeContext);
- return new_ec;
-}
-
-StackTrace VG_(extract_StackTrace) ( ExeContext* e )
-{ =20
- return e->ips;
-} =20
-
-/*--------------------------------------------------------------------*/
-/*--- end ---*/
-/*--------------------------------------------------------------------*/
Copied: trunk/coregrind/m_errormgr.c (from rev 3550, trunk/coregrind/erro=
rmgr.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-24 00:21:01 UTC (rev 3550)
+++ trunk/coregrind/m_errormgr.c 2005-04-24 12:33:12 UTC (rev 3555)
@@ -0,0 +1,1031 @@
+
+/*--------------------------------------------------------------------*/
+/*--- Management of error messages. m_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 t...
[truncated message content] |
|
From: <sv...@va...> - 2005-04-24 12:19:22
|
Author: sewardj Date: 2005-04-24 13:19:13 +0100 (Sun, 24 Apr 2005) New Revision: 3554 Added: trunk/coregrind/README_MODULES.txt Modified: trunk/coregrind/Makefile.am Log: Add statement-of-intent re top level module structure. 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-24 11:22:44 UTC (rev 3553) +++ trunk/coregrind/Makefile.am 2005-04-24 12:19:13 UTC (rev 3554) @@ -37,7 +37,7 @@ =20 EXTRA_DIST =3D \ valgrind.vs \ - gen_toolint.pl toolfuncs.def + gen_toolint.pl toolfuncs.def README_MODULES.txt =20 BUILT_SOURCES =3D vg_toolint.c vg_toolint.h CLEANFILES =3D vg_toolint.c vg_toolint.h Added: trunk/coregrind/README_MODULES.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/README_MODULES.txt 2005-04-24 11:22:44 UTC (rev 3553) +++ trunk/coregrind/README_MODULES.txt 2005-04-24 12:19:13 UTC (rev 3554) @@ -0,0 +1,58 @@ + +Our long term goal is to move to structure Valgrind's top level as a +set of well-defined modules. Much of the difficulty in maintaining +the beast is caused by the lack of clear boundaries, definitions and +semantics for subsystems (modules), and in particular a lack of +clarity about which modules may depend on which others. The ongoing +modularisation activities are aimed at dealing with this problem. + +Architecture dependent stuff will be chopped up and placed into the +relevant modules. Since the system's top level is now to be +structured as modules with clearly delimited areas of functionality, +directories such as 'amd64', 'amd64-linux', etc, cannot continue to +exist long-term. These trees contain mish-mashes of functionality +from multiple different modules, and so make no sense as top-level +entities in a scheme where all top-level entities are modules. + +This process is ongoing. Consequently some of the code in coregrind/ +has been bought into the module structure, but much hasn't. A naming +scheme distinguishes the done vs not-done stuff: + + Consider a module of name 'foo'. =20 + + If 'foo' is implemented in a single C file, and requires no other + files, it will live in coregrind/m_foo.c. + + Otherwise (if 'foo' requires more than one C file, or more than + zero private header files, or any other kind of auxiliary stuff) + then it will live in the directory coregrind/m_foo. + +Each module 'foo' must have two associated header files which describe +its public (exported) interface: + + include/pub_tool_foo.h + coregrind/pub_core_foo.h + +pub_tool_foo.h describes that part of the module's functionality that +is visible to tools. Hopefully this can be minimal or zero. The file +must still exist even if it defines nothing. + +pub_core_foo.h describes functionality that is visible to other +modules in the core. This is a strict superset of the visible-to-tool +functionality. + +Consequently, pub_core_foo.h may #include pub_tool_foo.h, but not the +other way round. + +No module may include the private headers of any other module. If a +type/enum/function/struct/whatever is stated in neither +include/pub_tool_foo.h nor coregrind/pub_core_foo.h then module 'foo' +DOES NOT EXPORT IT. + +Over time it is hoped to develop some simple Perl scripts to scan +source files for #includes so as to mechanically enforce these rules. +One of the most infuriating aspects of C is the total lack of support +for building properly abstracted subsystems. This is in sharp +comparison to languages such as Modula3, Haskell, ML, all of which +have support for modules built into the language, and hence such +boundaries are enforceable by the compiler. |
|
From: <sv...@va...> - 2005-04-24 11:23:01
|
Author: sewardj
Date: 2005-04-24 12:22:44 +0100 (Sun, 24 Apr 2005)
New Revision: 3553
Modified:
trunk/coregrind/vg_transtab.c
Log:
Add initialisation-order sanity checks.
Modified: trunk/coregrind/vg_transtab.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_transtab.c 2005-04-24 11:05:55 UTC (rev 3552)
+++ trunk/coregrind/vg_transtab.c 2005-04-24 11:22:44 UTC (rev 3553)
@@ -203,6 +203,10 @@
/*global*/ UInt* VG_(tt_fastN)[VG_TT_FAST_SIZE];
=20
=20
+/* Make sure we're not used before initialisation. */
+static Bool init_done =3D False;
+
+
/*------------------ STATS DECLS ------------------*/
=20
/* Number of fast-cache updates and flushes done. */
@@ -330,6 +334,7 @@
UChar* srcP;
UChar* dstP;
=20
+ vg_assert(init_done);
vg_assert(vge->n_used >=3D 1 && vge->n_used <=3D 3);
vg_assert(code_len > 0 && code_len < 20000);
=20
@@ -429,6 +434,8 @@
Bool upd_cache )
{
Int i, j, k, kstart, sno;
+
+ vg_assert(init_done);
/* Find the initial probe point just once. It will be the same in
all sectors and avoids multiple expensive % operations. */
n_full_lookups++;
@@ -516,6 +523,8 @@
Int sno, i;
Bool anyDeleted =3D False;
=20
+ vg_assert(init_done);
+
for (sno =3D 0; sno < N_SECTORS; sno++) {
if (sectors[sno].tc =3D=3D NULL)
continue;
@@ -553,6 +562,9 @@
{
Int i, avg_codeszQ;
=20
+ vg_assert(!init_done);
+ init_done =3D True;
+
/* Otherwise lots of things go wrong... */
vg_assert(sizeof(ULong) =3D=3D 8);
vg_assert(sizeof(Addr64) =3D=3D 8);
|
|
From: <sv...@va...> - 2005-04-24 11:06:01
|
Author: sewardj
Date: 2005-04-24 12:05:55 +0100 (Sun, 24 Apr 2005)
New Revision: 3552
Modified:
trunk/coregrind/vg_memory.c
trunk/include/tool.h.base
Log:
Update comment about stack management, and remove some unused
functions.
Modified: trunk/coregrind/vg_memory.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_memory.c 2005-04-24 10:41:53 UTC (rev 3551)
+++ trunk/coregrind/vg_memory.c 2005-04-24 11:05:55 UTC (rev 3552)
@@ -1035,37 +1035,43 @@
/*
The stack
~~~~~~~~~
- The stack's segment seems to be dynamically extended downwards
- by the kernel as the stack pointer moves down. Initially, a
- 1-page (4k) stack is allocated. When %esp moves below that for
- the first time, presumably a page fault occurs. The kernel
- detects that the faulting address is in the range from %esp upwards
- to the current valid stack. It then extends the stack segment
- downwards for enough to cover the faulting address, and resumes
- the process (invisibly). The process is unaware of any of this.
+ The stack's segment seems to be dynamically extended downwards by
+ the kernel as the stack pointer moves down. Initially, a 1-page
+ (4k) stack is allocated. When SP moves below that for the first
+ time, presumably a page fault occurs. The kernel detects that the
+ faulting address is in the range from SP - VGA_STACK_REDZONE_SIZE
+ upwards to the current valid stack. It then extends the stack
+ segment downwards for enough to cover the faulting address, and
+ resumes the process (invisibly). The process is unaware of any of
+ this.
=20
- That means that Valgrind can't spot when the stack segment is
- being extended. Fortunately, we want to precisely and continuously
- update stack permissions around %esp, so we need to spot all
- writes to %esp anyway.
+ That means that Valgrind can't spot when the stack segment is being
+ extended. Fortunately, we want to precisely and continuously
+ update stack permissions around SP, so we need to spot all writes
+ to SP anyway.
=20
- The deal is: when %esp is assigned a lower value, the stack is
- being extended. Create a secondary maps to fill in any holes
- between the old stack ptr and this one, if necessary. Then=20
- mark all bytes in the area just "uncovered" by this %esp change
- as write-only.
+ The deal is: when SP is assigned a lower value, the stack is being
+ extended. Create suitably-permissioned pages to fill in any holes
+ between the old stack ptr and this one, if necessary. Then mark
+ all bytes in the area just "uncovered" by this SP change as
+ write-only.
=20
- When %esp goes back up, mark the area receded over as unreadable
- and unwritable.
+ When SP goes back up, mark the area receded over as unreadable and
+ unwritable.
=20
- Just to record the %esp boundary conditions somewhere convenient:
- %esp always points to the lowest live byte in the stack. All
- addresses below %esp are not live; those at and above it are. =20
+ Just to record the SP boundary conditions somewhere convenient: SP
+ - VGA_STACK_REDZONE_SIZE always points to the lowest live byte in
+ the stack. All addresses below SP - VGA_STACK_REDZONE_SIZE are not
+ live; those at and above it are.
+
+ We do not concern ourselves here with the VGA_STACK_REDZONE_SIZE
+ bias; that is handled by new_mem_stack/die_mem_stack.
*/
=20
/* This function gets called if new_mem_stack and/or die_mem_stack are
- tracked by the tool, and one of the specialised cases (eg. new_mem_st=
ack_4)
- isn't used in preference */
+ tracked by the tool, and one of the specialised cases
+ (eg. new_mem_stack_4) isn't used in preference. =20
+*/
VGA_REGPARM(2)
void VG_(unknown_SP_update)( Addr old_SP, Addr new_SP )
{
@@ -1202,47 +1208,12 @@
return a >=3D VG_(shadow_base) && a < VG_(shadow_end);
}
=20
-Bool VG_(is_valgrind_addr)(Addr a)
-{
-vg_assert(0);
- return a >=3D VG_(valgrind_base) && a <=3D VG_(valgrind_last);
-}
-
-Addr VG_(get_client_base)(void)
-{
-vg_assert(0);
- return VG_(client_base);
-}
-
-Addr VG_(get_client_end)(void)
-{
-vg_assert(0);
- return VG_(client_end);
-}
-
-Addr VG_(get_client_size)(void)
-{
-vg_assert(0);
- return VG_(client_end)-VG_(client_base);
-}
-
-Addr VG_(get_shadow_base)(void)
-{
-vg_assert(0);
- return VG_(shadow_base);
-}
-
-Addr VG_(get_shadow_end)(void)
-{
-vg_assert(0);
- return VG_(shadow_end);
-}
-
Addr VG_(get_shadow_size)(void)
{
return VG_(shadow_end)-VG_(shadow_base);
}
=20
+
/*--------------------------------------------------------------------*/
/*--- Handling shadow memory ---*/
/*--------------------------------------------------------------------*/
Modified: trunk/include/tool.h.base
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/include/tool.h.base 2005-04-24 10:41:53 UTC (rev 3551)
+++ trunk/include/tool.h.base 2005-04-24 11:05:55 UTC (rev 3552)
@@ -478,21 +478,14 @@
extern void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who );
=20
extern Bool VG_(is_client_addr) (Addr a);
-extern Addr VG_(get_client_base)(void);
-extern Addr VG_(get_client_end) (void);
-extern Addr VG_(get_client_size)(void);
=20
extern Bool VG_(is_shadow_addr) (Addr a);
-extern Addr VG_(get_shadow_base)(void);
-extern Addr VG_(get_shadow_end) (void);
extern Addr VG_(get_shadow_size)(void);
=20
extern void *VG_(shadow_alloc)(UInt size);
=20
extern Bool VG_(is_addressable)(Addr p, SizeT sz, UInt prot);
=20
-extern Bool VG_(is_valgrind_addr)(Addr a);
-
/* Register an interest in apparently internal faults; used code which
wanders around dangerous memory (ie, leakcheck). The catcher is
not expected to return. */
|
|
From: <sv...@va...> - 2005-04-24 10:41:59
|
Author: sewardj Date: 2005-04-24 11:41:53 +0100 (Sun, 24 Apr 2005) New Revision: 3551 Removed: trunk/coregrind/dosyms Log: A leftover from the days of our own libpthread; now irrelevant. Deleted: trunk/coregrind/dosyms =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/dosyms 2005-04-24 00:21:01 UTC (rev 3550) +++ trunk/coregrind/dosyms 2005-04-24 10:41:53 UTC (rev 3551) @@ -1,31 +0,0 @@ -#!/bin/sh - -# A simple script to help me ensure that my libpthread.so looks -# from the outside, to the linker, identical to the original. - -nm /lib/libpthread.so.0 | grep " T " | cut -c 10- > orig-T -nm /lib/libpthread.so.0 | grep " D " | cut -c 10- > orig-D -nm /lib/libpthread.so.0 | grep " W " | cut -c 10- > orig-W -nm /lib/libpthread.so.0 | grep " U " | cut -c 10- > orig-U - -nm ./libpthread.so | grep " T " | cut -c 10- > mine-T -nm ./libpthread.so | grep " D " | cut -c 10- > mine-D -nm ./libpthread.so | grep " W " | cut -c 10- > mine-W -nm ./libpthread.so | grep " U " | cut -c 10- > mine-U - -echo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D TEXT orig vs mine =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -sdiff -w 80 orig-T mine-T -echo - -echo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D WEAK orig vs mine =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -sdiff -w 80 orig-W mine-W -echo - -echo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D DATA orig vs mine =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -sdiff -w 80 orig-D mine-D -echo - -echo =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D UNDF orig vs mine =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D -sdiff -w 80 orig-U mine-U -echo - |
|
From: <js...@ac...> - 2005-04-24 03:02:33
|
Nightly build on phoenix ( SuSE 9.1 ) started at 2005-04-24 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-24 02:35:51
|
Nightly build on dunsmere ( athlon, Fedora Core 3 ) started at 2005-04-24 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 == 176 tests, 78 stderr failures, 4 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/leakotron (stdout) 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 (stdout) 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-24 02:31:13
|
Nightly build on audi ( i686, Red Hat 9 ) started at 2005-04-24 03:25: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 == 175 tests, 15 stderr failures, 4 stdout failures ================= memcheck/tests/error_counts (stdout) 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/mempool (stderr) memcheck/tests/metadata (stdout) memcheck/tests/metadata (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/nanoleak_supp (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/scalar (stderr) memcheck/tests/scalar_exit_group (stderr) memcheck/tests/scalar_supp (stderr) memcheck/tests/trivialleak (stderr) none/tests/faultstatus (stderr) none/tests/x86/int (stderr) none/tests/yield (stdout) |
|
From: Tom H. <to...@co...> - 2005-04-24 02:26:21
|
Nightly build on dunsmere ( Fedora Core 3 ) started at 2005-04-24 03:20:04 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: 32239 Segmentation fault VALGRINDLIB=/tmp/valgrind.6634/valgrind/.in_place /tmp/valgrind.6634/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-24 02:22:40
|
Nightly build on audi ( Red Hat 9 ) started at 2005-04-24 03:15:01 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-24 02:20:55
|
Nightly build on alvis ( i686, Red Hat 7.3 ) started at 2005-04-24 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 == 174 tests, 20 stderr failures, 4 stdout failures ================= memcheck/tests/addressable (stderr) memcheck/tests/describe-block (stderr) memcheck/tests/error_counts (stdout) 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/match-overrun (stderr) memcheck/tests/mempool (stderr) memcheck/tests/metadata (stdout) memcheck/tests/metadata (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/nanoleak_supp (stderr) memcheck/tests/pointer-trace (stderr) memcheck/tests/scalar (stderr) memcheck/tests/scalar_exit_group (stderr) memcheck/tests/scalar_supp (stderr) memcheck/tests/threadederrno (stderr) memcheck/tests/trivialleak (stderr) memcheck/tests/vgtest_ume (stderr) none/tests/faultstatus (stderr) none/tests/x86/int (stderr) none/tests/yield (stdout) |
|
From: Tom H. <th...@cy...> - 2005-04-24 02:16:01
|
Nightly build on honda ( x86_64, Fedora Core 3 ) started at 2005-04-24 03:10: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 == 156 tests, 84 stderr failures, 20 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/memalign2 (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/mmaptest (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/nanoleak_supp (stderr) memcheck/tests/new_nothrow (stderr) memcheck/tests/new_override (stdout) memcheck/tests/new_override (stderr) memcheck/tests/null_socket (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/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 (stdout) 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 (stdout) memcheck/tests/threadederrno (stderr) 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) memcheck/tests/zeropage (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) |
|
From: Tom H. <th...@cy...> - 2005-04-24 02:11:41
|
Nightly build on alvis ( Red Hat 7.3 ) started at 2005-04-24 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-24 02:02:58
|
Nightly build on gill ( x86_64, Fedora Core 2 ) started at 2005-04-24 03:00: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 == 156 tests, 84 stderr failures, 20 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/memalign2 (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/mmaptest (stderr) memcheck/tests/nanoleak (stderr) memcheck/tests/nanoleak_supp (stderr) memcheck/tests/new_nothrow (stderr) memcheck/tests/new_override (stdout) memcheck/tests/new_override (stderr) memcheck/tests/null_socket (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/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 (stdout) 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 (stdout) memcheck/tests/threadederrno (stderr) 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) memcheck/tests/zeropage (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) |
|
From: Nicholas N. <nj...@cs...> - 2005-04-24 01:16:39
|
On Sun, 24 Apr 2005 sv...@va... wrote: > Log: > Add intercepts for operator new(unsigned long) and operator > new[](unsigned long). The 32-bit ones take unsigned int args, not > unsigned longs, and so the existing name-set did not capture them. The parameters are actually std::size_t, which should be 32-bits on 32-bit platforms and 64-bits on 64-bit platforms, so I'm confused by this change... N |
|
From: <sv...@va...> - 2005-04-24 00:26:41
|
Author: sewardj
Date: 2005-04-24 01:26:37 +0100 (Sun, 24 Apr 2005)
New Revision: 1139
Modified:
trunk/priv/host-amd64/isel.c
Log:
Handle a couple more memcheck-generated primops. With this, I can run
konqueror on memcheck on amd64.
Modified: trunk/priv/host-amd64/isel.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/priv/host-amd64/isel.c 2005-04-23 23:41:46 UTC (rev 1138)
+++ trunk/priv/host-amd64/isel.c 2005-04-24 00:26:37 UTC (rev 1139)
@@ -991,31 +991,20 @@
return hi16;
}
=20
-//.. if (e->Iex.Binop.op =3D=3D Iop_8HLto16) {
-//.. HReg hi8 =3D newVRegI(env);
-//.. HReg lo8 =3D newVRegI(env);
-//.. HReg hi8s =3D iselIntExpr_R(env, e->Iex.Binop.arg1);
-//.. HReg lo8s =3D iselIntExpr_R(env, e->Iex.Binop.arg2);
-//.. addInstr(env, mk_iMOVsd_RR(hi8s, hi8));
-//.. addInstr(env, mk_iMOVsd_RR(lo8s, lo8));
-//.. addInstr(env, X86Instr_Sh32(Xsh_SHL, 8, X86RM_Reg(hi8)));
-//.. addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFF), =
lo8));
-//.. addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo8), hi=
8));
-//.. return hi8;
-//.. }
-//..=20
-//.. if (e->Iex.Binop.op =3D=3D Iop_16HLto32) {
-//.. HReg hi16 =3D newVRegI(env);
-//.. HReg lo16 =3D newVRegI(env);
-//.. HReg hi16s =3D iselIntExpr_R(env, e->Iex.Binop.arg1);
-//.. HReg lo16s =3D iselIntExpr_R(env, e->Iex.Binop.arg2);
-//.. addInstr(env, mk_iMOVsd_RR(hi16s, hi16));
-//.. addInstr(env, mk_iMOVsd_RR(lo16s, lo16));
-//.. addInstr(env, X86Instr_Sh32(Xsh_SHL, 16, X86RM_Reg(hi16)))=
;
-//.. addInstr(env, X86Instr_Alu32R(Xalu_AND, X86RMI_Imm(0xFFFF)=
, lo16));
-//.. addInstr(env, X86Instr_Alu32R(Xalu_OR, X86RMI_Reg(lo16), h=
i16));
-//.. return hi16;
-//.. }
+ if (e->Iex.Binop.op =3D=3D Iop_8HLto16) {
+ HReg hi8 =3D newVRegI(env);
+ HReg lo8 =3D newVRegI(env);
+ HReg hi8s =3D iselIntExpr_R(env, e->Iex.Binop.arg1);
+ HReg lo8s =3D iselIntExpr_R(env, e->Iex.Binop.arg2);
+ addInstr(env, mk_iMOVsd_RR(hi8s, hi8));
+ addInstr(env, mk_iMOVsd_RR(lo8s, lo8));
+ addInstr(env, AMD64Instr_Sh64(Ash_SHL, 8, AMD64RM_Reg(hi8)));
+ addInstr(env, AMD64Instr_Alu64R(
+ Aalu_AND, AMD64RMI_Imm(0xFF), lo8));
+ addInstr(env, AMD64Instr_Alu64R(
+ Aalu_OR, AMD64RMI_Reg(lo8), hi8));
+ return hi8;
+ }
=20
if (e->Iex.Binop.op =3D=3D Iop_MullS32
|| e->Iex.Binop.op =3D=3D Iop_MullS16
@@ -1282,7 +1271,7 @@
addInstr(env, AMD64Instr_Set64(cond,dst));
return dst;
}
-//.. case Iop_1Sto8:
+ case Iop_1Sto8:
case Iop_1Sto16:
case Iop_1Sto32:
case Iop_1Sto64: {
|
|
From: <sv...@va...> - 2005-04-24 00:21:06
|
Author: njn
Date: 2005-04-24 01:21:01 +0100 (Sun, 24 Apr 2005)
New Revision: 3550
Modified:
trunk/cachegrind/cg_main.c
Log:
Inline function that's only used once.
Modified: trunk/cachegrind/cg_main.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/cachegrind/cg_main.c 2005-04-24 00:04:42 UTC (rev 3549)
+++ trunk/cachegrind/cg_main.c 2005-04-24 00:21:01 UTC (rev 3550)
@@ -779,15 +779,6 @@
=20
static Char* cachegrind_out_file;
=20
-static void file_err ( void )
-{
- VG_(message)(Vg_UserMsg,
- "error: can't open cache simulation output file `%s'",
- cachegrind_out_file );
- VG_(message)(Vg_UserMsg,
- " ... so simulation results will be missing.");
-}
-
static void fprint_lineCC(Int fd, lineCC* n)
{
Char buf[512];
@@ -819,7 +810,11 @@
if (fd < 0) {
// If the file can't be opened for whatever reason (conflict
// between multiple cachegrinded processes?), give up now.
- file_err();=20
+ VG_(message)(Vg_UserMsg,
+ "error: can't open cache simulation output file `%s'",
+ cachegrind_out_file );
+ VG_(message)(Vg_UserMsg,
+ " ... so simulation results will be missing.");
return;
}
=20
|
|
From: <sv...@va...> - 2005-04-24 00:04:47
|
Author: sewardj Date: 2005-04-24 01:04:42 +0100 (Sun, 24 Apr 2005) New Revision: 3549 Modified: trunk/NOTES.txt trunk/coregrind/vg_replace_malloc.c Log: Add intercepts for operator new(unsigned long) and operator new[](unsigned long). The 32-bit ones take unsigned int args, not unsigned longs, and so the existing name-set did not capture them. Modified: trunk/NOTES.txt =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=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/NOTES.txt 2005-04-23 23:26:29 UTC (rev 3548) +++ trunk/NOTES.txt 2005-04-24 00:04:42 UTC (rev 3549) @@ -1,14 +1,20 @@ =20 23 Apr 05 (memcheck-on-amd64 notes) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* If a thread is given an initial stack with address range [lo .. hi], + we need to tell memcheck that the area [lo - VGA_STACK_REDZONE_SIZE + .. hi] is valid, rather than just [lo .. hi] as has been the case on + x86-only systems. However, am not sure where to look for the call + into memcheck that states the new stack area. =20 -If a thread is given an initial stack with address range [lo .. hi], -we need to tell memcheck that the area [lo - VGA_STACK_REDZONE_SIZE -.. hi] is valid, rather than just [lo .. hi] as has been the case on -x86-only systems. However, am not sure where to look for the=20 -call into memcheck that states the new stack area. +* vg_replace_malloc.c: need to create intercepts for + 64-bit versions of + operator new(unsigned, std::nothrow_t const&) + and=20 + operator new[](unsigned, std::nothrow_t const&) =20 =20 + 9 Apr 05 (starting work on memcheck for 32/64-bit and big/little endian) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * get rid of memcheck/mc_asm.h and include/tool_asm.h. I think=20 Modified: trunk/coregrind/vg_replace_malloc.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_replace_malloc.c 2005-04-23 23:26:29 UTC (rev 3548= ) +++ trunk/coregrind/vg_replace_malloc.c 2005-04-24 00:04:42 UTC (rev 3549= ) @@ -215,19 +215,27 @@ ALLOC_or_NULL(m_libc_dot_so_dot_6, malloc, malloc); //ALLOC_or_NULL(m_libpgc_dot_so, malloc, malloc); =20 -// operator new(unsigned int), GNU mangling +// operator new(unsigned int), GNU mangling, 32-bit platforms ALLOC_or_BOMB(m_libstc_plus_plus_star, builtin_new, __builtin_new); ALLOC_or_BOMB(m_libc_dot_so_dot_6, builtin_new, __builtin_new); =20 ALLOC_or_BOMB(m_libstc_plus_plus_star, __builtin_new, __builtin_new); ALLOC_or_BOMB(m_libc_dot_so_dot_6, __builtin_new, __builtin_new); =20 +// TODO: these should only exist on 32-bit platforms ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znwj, __builtin_new); ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znwj, __builtin_new); =20 +// TODO: these should only exist on 64-bit platforms +// operator new(unsigned long), GNU mangling, 64-bit platforms +ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znwm, __builtin_new); +ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znwm, __builtin_new); + + // operator new(unsigned int), ARM/cfront mangling //ALLOC_or_BOMB(m_libpgc_dot_so, __nw__FUi, __builtin_new); =20 +// TODO: create 64-bit version // operator new(unsigned, std::nothrow_t const&), GNU mangling ALLOC_or_NULL(m_libstc_plus_plus_star, _ZnwjRKSt9nothrow_t, __builtin_n= ew); ALLOC_or_NULL(m_libc_dot_so_dot_6, _ZnwjRKSt9nothrow_t, __builtin_n= ew); @@ -235,9 +243,17 @@ // operator new[](unsigned int), GNU mangling ALLOC_or_BOMB(m_libstc_plus_plus_star, __builtin_vec_new, __builtin_vec_= new ); ALLOC_or_BOMB(m_libc_dot_so_dot_6, __builtin_vec_new, __builtin_vec_= new ); + +// TODO: these should only exist on 32-bit platforms ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znaj, __builtin_vec_= new ); ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znaj, __builtin_vec_= new ); =20 +// TODO: these should only exist on 64-bit platforms +// operator new[](unsigned long), GNU mangling, 64-bit platforms +ALLOC_or_BOMB(m_libstc_plus_plus_star, _Znam, __builtin_vec_= new ); +ALLOC_or_BOMB(m_libc_dot_so_dot_6, _Znam, __builtin_vec_= new ); + +// TODO: create 64-bit version // operator new[](unsigned, std::nothrow_t const&), GNU mangling ALLOC_or_NULL(m_libstc_plus_plus_star, _ZnajRKSt9nothrow_t, __builtin_ve= c_new ); ALLOC_or_NULL(m_libc_dot_so_dot_6, _ZnajRKSt9nothrow_t, __builtin_ve= c_new ); |