Merged r9653..r9655 (fixed terminal signal handling in Darwin) from DARWIN

branch.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9656
This commit is contained in:
Nicholas Nethercote 2009-04-28 01:55:01 +00:00
parent b46800c8b7
commit c601f8a1e4
7 changed files with 68 additions and 91 deletions

View File

@ -1137,6 +1137,24 @@ void VG_(kill_self)(Int sigNo)
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
@ -1208,15 +1226,17 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid)
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;
@ -1299,7 +1319,7 @@ static void default_action(const vki_siginfo_t *info, ThreadId tid)
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");
@ -1744,7 +1764,24 @@ void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *u
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
@ -1812,7 +1849,7 @@ void sync_signalhandler ( Int sigNo, vki_siginfo_t *info, struct vki_ucontext *u
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, "

View File

@ -23,9 +23,11 @@ endif
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 \

View File

@ -93,12 +93,12 @@ static void test5()
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 @@ int main()
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));

View File

@ -15,8 +15,8 @@ Invalid write of size 1
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 @@ 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........
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)

View File

@ -1,70 +0,0 @@
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

View File

@ -1,2 +1,2 @@
prog: addressable
stderr_filter: filter_allocs
stderr_filter: filter_addressable

View File

@ -0,0 +1,7 @@
#! /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/'