branch.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9656
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 );
+#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
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;
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");
info->si_code = (Short)info->si_code;
#endif
- if (info->si_code <= VKI_SI_USER) {
+ /* // debug code:
+ if (0) {
+ VG_(printf)("info->si_signo %d\n", info->si_signo);
+ VG_(printf)("info->si_errno %d\n", info->si_errno);
+ VG_(printf)("info->si_code %d\n", info->si_code);
+ VG_(printf)("info->si_pid %d\n", info->si_pid);
+ VG_(printf)("info->si_uid %d\n", info->si_uid);
+ VG_(printf)("info->si_status %d\n", info->si_status);
+ VG_(printf)("info->si_addr %p\n", info->si_addr);
+ }
+ */
+
+ /* Figure out if the signal is being sent from outside the process.
+ (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_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
queue_signal(0, info); /* shared pending */
return;
- }
+ } /* if (!is_signal_from_kernel(info->si_code)) */
if (VG_(clo_trace_signals)) {
VG_(message)(Vg_DebugMsg, "signal %d arrived ... si_code=%d, "
DIST_SUBDIRS = x86 amd64 linux 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 \
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);
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));
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
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)
+++ /dev/null
-
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis, rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Unaddressable byte(s) found during client check request
- at 0x........: test2 (addressable.c:48)
- by 0x........: main (addressable.c:125)
- Address 0x........ is not stack'd, malloc'd or (recently) free'd
-
-Invalid write of size 1
- at 0x........: test2 (addressable.c:51)
- 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........
- at 0x........: test2 (addressable.c:51)
- by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis, rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-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........
- at 0x........: test4 (addressable.c:74)
- by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis, rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Uninitialised byte(s) found during client check request
- at 0x........: test5 (addressable.c:85)
- by 0x........: main (addressable.c:125)
- Address 0x........ is 10 bytes inside a block of size 20480 client-defined
- at 0x........: test5 (addressable.c:82)
- by 0x........: main (addressable.c:125)
-
-Uninitialised byte(s) found during client check request
- at 0x........: test5 (addressable.c:91)
- by 0x........: main (addressable.c:125)
- Address 0x........ is 20 bytes inside a block of size 20480 client-defined
- at 0x........: test5 (addressable.c:82)
- by 0x........: main (addressable.c:125)
-
-ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis, rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
-Use --track-origins=yes to see where uninitialised values come from
-
-ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
-malloc/free: in use at exit: ... bytes in ... blocks.
-malloc/free: ... allocs, ... frees, ... bytes allocated.
-For a detailed leak analysis, rerun with: --leak-check=yes
-For counts of detected errors, rerun with: -v
prog: addressable
-stderr_filter: filter_allocs
+stderr_filter: filter_addressable
--- /dev/null
+#! /bin/sh
+
+./filter_allocs |
+perl -p -e 's/(default action of signal) [0-9]+ \(SIG(SEGV|BUS)\)/$1 N \(SIGSEGV or SIGBUS\)/' |
+perl -p -e 's/(Bad permissions for mapped region|Access not within mapped region|Non-existent physical address) at address 0x/Bad memory (SIGSEGV or SIGBUS) at address 0x/'
+
+