|
From: <sv...@va...> - 2009-04-28 01:20:01
|
Author: njn
Date: 2009-04-28 02:19:54 +0100 (Tue, 28 Apr 2009)
New Revision: 9653
Log:
Fixed handling of some terminal signals on Darwin. Also made
memcheck/tests/addressable more portable.
memcheck/tests/{addressable,badjump,supp_unknown} now all pass on Darwin.
Modified:
branches/DARWIN/coregrind/m_signals.c
branches/DARWIN/memcheck/tests/Makefile.am
branches/DARWIN/memcheck/tests/addressable.c
branches/DARWIN/memcheck/tests/addressable.stderr.exp
branches/DARWIN/memcheck/tests/addressable.vgtest
Modified: branches/DARWIN/coregrind/m_signals.c
===================================================================
--- branches/DARWIN/coregrind/m_signals.c 2009-04-28 00:15:51 UTC (rev 9652)
+++ branches/DARWIN/coregrind/m_signals.c 2009-04-28 01:19:54 UTC (rev 9653)
@@ -1258,6 +1258,28 @@
VG_(sigprocmask)(VKI_SIG_SETMASK, &origmask, NULL);
}
+// The si_code describes where the signal came from. Some come from the
+// kernel, eg.: seg faults, illegal opcodes. Some come from the user, eg.:
+// from kill() (SI_USER), or timer_settime() (SI_TIMER), or an async I/O
+// request (SI_ASYNCIO). There's lots of implementation-defined leeway in
+// POSIX, but the user vs. kernal distinction is what we want here.
+static Bool is_signal_from_kernel(int si_code)
+{
+#if defined(VGO_linux) || defined(VGO_aix5)
+ // On Linux, SI_USER is zero, negative values are from the user, positive
+ // values are from the kernel. There are SI_FROMUSER and SI_FROMKERNEL
+ // macros but we don't use them here because other platforms don't have
+ // them.
+ return ( si_code > VKI_SI_USER ? True : False );
+#elif defined(VGO_darwin)
+ // On Darwin, SI_USER is 0x10001, values greater than that are from the
+ // user, small positive integers are from the kernel.
+ return ( si_code < VKI_SI_USER ? True : False );
+#else
+# error Unknown OS
+#endif
+}
+
/*
Perform the default action of a signal. If the signal is fatal, it
marks all threads as needing to exit, but it doesn't actually kill
@@ -1334,15 +1356,17 @@
core = False;
}
- if ( (VG_(clo_verbosity) > 1 || (could_core && info->si_code > VKI_SI_USER))
- && !VG_(clo_xml) ) {
+ if ( (VG_(clo_verbosity) > 1 ||
+ (could_core && is_signal_from_kernel(info->si_code))
+ ) &&
+ !VG_(clo_xml) ) {
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg,
"Process terminating with default action of signal %d (%s)%s",
sigNo, signame(sigNo), core ? ": dumping core" : "");
/* Be helpful - decode some more details about this fault */
- if (info->si_code > VKI_SI_USER) {
+ if (is_signal_from_kernel(info->si_code)) {
const Char *event = NULL;
Bool haveaddr = True;
@@ -1425,7 +1449,7 @@
VG_(pp_ExeContext)( ec );
}
if (sigNo == VKI_SIGSEGV
- && info && info->si_code > VKI_SI_USER
+ && info && is_signal_from_kernel(info->si_code)
&& info->si_code == VKI_SEGV_MAPERR) {
VG_(message)(Vg_UserMsg, " If you believe this happened as a "
"result of a stack overflow in your");
@@ -1935,7 +1959,6 @@
void sync_signalhandler ( Int sigNo,
vki_siginfo_t *info, struct vki_ucontext *uc )
{
- Bool is_from_outside_process;
ThreadId tid = VG_(lwpid_to_vgtid)(VG_(gettid)());
if (0)
@@ -1974,26 +1997,11 @@
*/
/* Figure out if the signal is being sent from outside the process.
- (Why do we care?) If it is, then treat it more like an async
- signal than a sync signal -- that is, merely queue it for later
- delivery. It seems the logic for detecting which case is which
- differs between Linux/AIX and Darwin. */
-# if defined(VGO_linux) || defined(VGO_aix5)
- is_from_outside_process = info->si_code <= VKI_SI_USER;
-# elif defined(VGO_darwin)
- /* see "Values for si_code" in /usr/include/sys/signal.h;
- all the XXX_NOOP values are zero. */
- /* Bugger it, let's just deliver the damn thing as if it was a sync
- signal from inside the process. I really don't understand
- enough about the rationale behind this logic to make informed
- decisions. JRS, 3 Mar 09. */
- is_from_outside_process = False;
- /* info->si_code == 0; */ /* originally .. */
-# else
-# error "Unknown OS"
-# endif
+ (Why do we care?) If the signal is from the user rather than the
+ kernel,, then treat it more like an async signal than a sync signal --
+ that is, merely queue it for later delivery. */
- if (is_from_outside_process) {
+ if (!is_signal_from_kernel(info->si_code)) {
/* If some user-process sent us one of these signals (ie,
they're not the result of a faulting instruction), then treat
it as an async signal. This is tricky because we could get
@@ -2061,7 +2069,7 @@
queue_signal(0, info); /* shared pending */
return;
- } /* if (is_from_outside_process) */
+ } /* if (!is_signal_from_kernel(info->si_code)) */
if (VG_(clo_trace_signals)) {
VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, "
Modified: branches/DARWIN/memcheck/tests/Makefile.am
===================================================================
--- branches/DARWIN/memcheck/tests/Makefile.am 2009-04-28 00:15:51 UTC (rev 9652)
+++ branches/DARWIN/memcheck/tests/Makefile.am 2009-04-28 01:19:54 UTC (rev 9653)
@@ -26,9 +26,11 @@
DIST_SUBDIRS = x86 amd64 linux darwin x86-linux .
-noinst_SCRIPTS = filter_allocs \
- filter_stderr filter_xml \
- filter_varinfo3
+noinst_SCRIPTS = \
+ filter_addressable \
+ filter_allocs \
+ filter_stderr filter_xml \
+ filter_varinfo3
EXTRA_DIST = $(noinst_SCRIPTS) \
addressable.stderr.exp addressable.stdout.exp addressable.vgtest \
Modified: branches/DARWIN/memcheck/tests/addressable.c
===================================================================
--- branches/DARWIN/memcheck/tests/addressable.c 2009-04-28 00:15:51 UTC (rev 9652)
+++ branches/DARWIN/memcheck/tests/addressable.c 2009-04-28 01:19:54 UTC (rev 9653)
@@ -93,12 +93,12 @@
static struct test {
void (*test)(void);
- int sig;
+ int faults;
} tests[] = {
{ test1, 0 },
- { test2, SIGSEGV },
+ { test2, 1 },
{ test3, 0 },
- { test4, SIGSEGV },
+ { test4, 1 },
{ test5, 0 },
};
static const int n_tests = sizeof(tests)/sizeof(*tests);
@@ -140,18 +140,19 @@
if (WIFSIGNALED(status)) {
assert(WTERMSIG(status) != 0);
- if (WTERMSIG(status) == tests[i].sig)
+ if (1 == tests[i].faults &&
+ (WTERMSIG(status) == SIGSEGV ||
+ WTERMSIG(status) == SIGBUS))
printf("PASS\n");
else
printf("died with unexpected signal %d\n",
WTERMSIG(status));
} else if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == 0) {
- if (tests[i].sig == 0)
+ if (tests[i].faults == 0)
printf("PASS\n");
else
- printf("exited without expected signal %d\n",
- tests[i].sig);
+ printf("exited without expected SIGSEGV or SIGBUS signal\n");
} else
printf("exited with unexpected status %d\n",
WEXITSTATUS(status));
Modified: branches/DARWIN/memcheck/tests/addressable.stderr.exp
===================================================================
--- branches/DARWIN/memcheck/tests/addressable.stderr.exp 2009-04-28 00:15:51 UTC (rev 9652)
+++ branches/DARWIN/memcheck/tests/addressable.stderr.exp 2009-04-28 01:19:54 UTC (rev 9653)
@@ -15,8 +15,8 @@
by 0x........: main (addressable.c:125)
Address 0x........ is not stack'd, malloc'd or (recently) free'd
-Process terminating with default action of signal 11 (SIGSEGV)
- Access not within mapped region at address 0x........
+Process terminating with default action of signal N (SIGSEGV or SIGBUS)
+ Bad memory (SIGSEGV or SIGBUS) at address 0x........
at 0x........: test2 (addressable.c:51)
by 0x........: main (addressable.c:125)
If you believe this happened as a result of a stack overflow in your
@@ -36,8 +36,8 @@
For a detailed leak analysis, rerun with: --leak-check=yes
For counts of detected errors, rerun with: -v
-Process terminating with default action of signal 11 (SIGSEGV)
- Bad permissions for mapped region at address 0x........
+Process terminating with default action of signal N (SIGSEGV or SIGBUS)
+ Bad memory (SIGSEGV or SIGBUS) at address 0x........
at 0x........: test4 (addressable.c:74)
by 0x........: main (addressable.c:125)
Modified: branches/DARWIN/memcheck/tests/addressable.vgtest
===================================================================
--- branches/DARWIN/memcheck/tests/addressable.vgtest 2009-04-28 00:15:51 UTC (rev 9652)
+++ branches/DARWIN/memcheck/tests/addressable.vgtest 2009-04-28 01:19:54 UTC (rev 9653)
@@ -1,2 +1,2 @@
prog: addressable
-stderr_filter: filter_allocs
+stderr_filter: filter_addressable
|