ATF test for SIGBUS => BUS_ADRALN (invalid address alignment).
That one is tedious to test under x86: alignment exceptions are not reported by this architecture unless you ask for them explicitely (by setting the PSL_AC bit). The brokenness does not end there: %cr2 should contain the address where the unaligned access occured, alas, it does not. I am not aware of other architectures where this could happen. Still, my knowledge is limited; if there is one, feel free to send me a mail and I will update the test accordingly. Adding insult to injury, this test can fail in various funny ways with VMs: - under x86 QEMU, no trap() happens. As ring 3 code stays almost untouched by QEMU VMM, I suppose the exception can only be triggered when the host itself is capable of catching unaligned accesses. - under Virtual Box with HVM support, i386 works fine, but amd64 fails with a SIGILL (Illegal instruction) that happens right before entering the signal handler. No idea why, and trying to debug it with gdb freezes the VM (including ddb breaks). Anyway, tested with: - i386: P4 host, anita, Virtual Box HVM (Mac OS X) - amd64: anita, Virtual Box HVM (Mac OS X) XXX I would appreciate if someone could test it under a real amd64 host with an up-to-date kernel, so I can reasonably assume that the culprit is Virtual Box and not our amd64 port (my test machine being off line I cannot do it myself). Results from other arches would be a plus too. Initial issue reported by Nicolas Joly on port-amd64. Thanks!
This commit is contained in:
parent
f90c9c2dab
commit
c5252d3225
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: t_siginfo.c,v 1.14 2012/03/18 07:14:08 jruoho Exp $ */
|
||||
/* $NetBSD: t_siginfo.c,v 1.15 2012/04/20 00:40:31 jym Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010 The NetBSD Foundation, Inc.
|
||||
|
@ -48,6 +48,9 @@
|
|||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
/* for sigbus */
|
||||
char *addr;
|
||||
|
||||
/* for sigchild */
|
||||
pid_t child;
|
||||
int code;
|
||||
|
@ -405,6 +408,70 @@ ATF_TC_BODY(sigsegv, tc)
|
|||
atf_tc_fail("Test did not fault as expected");
|
||||
}
|
||||
|
||||
static void
|
||||
sigbus_action(int signo, siginfo_t *info, void *ptr)
|
||||
{
|
||||
|
||||
sig_debug(signo, info, (ucontext_t *)ptr);
|
||||
|
||||
ATF_REQUIRE_EQ(info->si_signo, SIGBUS);
|
||||
ATF_REQUIRE_EQ(info->si_errno, 0);
|
||||
ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN);
|
||||
|
||||
if (strcmp(atf_config_get("atf_arch"), "i386") == 0 ||
|
||||
strcmp(atf_config_get("atf_arch"), "x86_64") == 0) {
|
||||
atf_tc_expect_fail("x86 architecture does not correctly "
|
||||
"report the address where the unaligned access occured");
|
||||
}
|
||||
|
||||
ATF_REQUIRE_EQ(info->si_addr, (void *)addr);
|
||||
atf_tc_pass();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
ATF_TC(sigbus_adraln);
|
||||
ATF_TC_HEAD(sigbus_adraln, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Checks that signal trampoline correctly calls SIGBUS handler "
|
||||
"for invalid address alignment");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(sigbus_adraln, tc)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = sigbus_action;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaction(SIGBUS, &sa, NULL);
|
||||
|
||||
/* Enable alignement checks for x86. 0x40000 is PSL_AC. */
|
||||
#if defined(__i386__)
|
||||
__asm__("pushf; orl $0x40000, (%esp); popf");
|
||||
#elif defined(__amd64__)
|
||||
__asm__("pushf; orl $0x40000, (%rsp); popf");
|
||||
#endif
|
||||
|
||||
addr = calloc(2, sizeof(int));
|
||||
ATF_REQUIRE(addr != NULL);
|
||||
|
||||
if (strcmp(atf_config_get("atf_arch"), "i386") == 0 ||
|
||||
strcmp(atf_config_get("atf_arch"), "x86_64") == 0) {
|
||||
if (system("cpuctl identify 0 | grep -q QEMU") == 0) {
|
||||
atf_tc_expect_fail("QEMU fails to trap unaligned "
|
||||
"accesses");
|
||||
}
|
||||
}
|
||||
|
||||
/* Force an unaligned access */
|
||||
addr++;
|
||||
ATF_REQUIRE_EQ(*(volatile int *)addr, 0);
|
||||
|
||||
atf_tc_fail("Test did not fault as expected");
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
|
@ -415,6 +482,7 @@ ATF_TP_ADD_TCS(tp)
|
|||
ATF_TP_ADD_TC(tp, sigfpe_flt);
|
||||
ATF_TP_ADD_TC(tp, sigfpe_int);
|
||||
ATF_TP_ADD_TC(tp, sigsegv);
|
||||
ATF_TP_ADD_TC(tp, sigbus_adraln);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue