1 /* $NetBSD: t_siginfo.c,v 1.24 2014/11/04 00:20:19 justin Exp $ */
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/inttypes.h>
34 #include <sys/resource.h>
35 #include <sys/sysctl.h>
37 #include <sys/ucontext.h>
51 #elif defined(_FLOAT_IEEE754)
66 sig_atomic_t fltdiv_signalled = 0;
67 sig_atomic_t intdiv_signalled = 0;
70 sig_debug(int signo, siginfo_t *info, ucontext_t *ctx)
74 printf("%d %p %p\n", signo, info, ctx);
76 printf("si_signo=%d\n", info->si_signo);
77 printf("si_errno=%d\n", info->si_errno);
78 printf("si_code=%d\n", info->si_code);
79 printf("si_value.sival_int=%d\n", info->si_value.sival_int);
82 printf("uc_flags 0x%x\n", ctx->uc_flags);
83 printf("uc_link %p\n", ctx->uc_link);
84 for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++)
85 printf("uc_sigmask[%d] 0x%x\n", i,
86 ctx->uc_sigmask.__bits[i]);
87 printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp,
88 (unsigned long)ctx->uc_stack.ss_size,
89 ctx->uc_stack.ss_flags);
91 for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++)
92 printf("uc_mcontext.greg[%d] 0x%lx\n", i,
93 (long)ctx->uc_mcontext.__gregs[i]);
99 sigalrm_action(int signo, siginfo_t *info, void *ptr)
102 sig_debug(signo, info, (ucontext_t *)ptr);
104 ATF_REQUIRE_EQ(info->si_signo, SIGALRM);
105 ATF_REQUIRE_EQ(info->si_code, SI_TIMER);
106 ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL);
114 ATF_TC_HEAD(sigalarm, tc)
117 atf_tc_set_md_var(tc, "descr",
118 "Checks that signal trampoline correctly calls SIGALRM handler");
121 ATF_TC_BODY(sigalarm, tc)
124 sa.sa_flags = SA_SIGINFO;
125 sa.sa_sigaction = sigalrm_action;
126 sigemptyset(&sa.sa_mask);
127 sigaction(SIGALRM, &sa, NULL);
132 atf_tc_fail("SIGALRM handler wasn't called");
136 sigchild_action(int signo, siginfo_t *info, void *ptr)
139 printf("info=%p\n", info);
140 printf("ptr=%p\n", ptr);
141 printf("si_signo=%d\n", info->si_signo);
142 printf("si_errno=%d\n", info->si_errno);
143 printf("si_code=%d\n", info->si_code);
144 printf("si_uid=%d\n", info->si_uid);
145 printf("si_pid=%d\n", info->si_pid);
146 printf("si_status=%d\n", info->si_status);
148 printf("si_utime=%lu\n", (unsigned long int)info->si_utime);
149 printf("si_stime=%lu\n", (unsigned long int)info->si_stime);
152 ATF_REQUIRE_EQ(info->si_code, code);
153 ATF_REQUIRE_EQ(info->si_signo, SIGCHLD);
154 ATF_REQUIRE_EQ(info->si_uid, getuid());
155 ATF_REQUIRE_EQ(info->si_pid, child);
156 if (WIFEXITED(info->si_status))
157 ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status);
158 else if (WIFSTOPPED(info->si_status))
159 ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status);
160 else if (WIFSIGNALED(info->si_status))
161 ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status);
165 setchildhandler(void (*action)(int, siginfo_t *, void *))
168 sa.sa_flags = SA_SIGINFO;
169 sa.sa_sigaction = action;
170 sigemptyset(&sa.sa_mask);
171 sigaction(SIGCHLD, &sa, NULL);
180 (void)getrlimit(RLIMIT_CORE, &rlim);
181 rlim.rlim_cur = rlim.rlim_max;
182 (void)setrlimit(RLIMIT_CORE, &rlim);
184 setchildhandler(sigchild_action);
186 sigaddset(&set, SIGCHLD);
187 sigprocmask(SIG_BLOCK, &set, NULL);
190 ATF_TC(sigchild_normal);
191 ATF_TC_HEAD(sigchild_normal, tc)
194 atf_tc_set_md_var(tc, "descr",
195 "Checks that signal trampoline correctly calls SIGCHLD handler "
196 "when child exits normally");
199 ATF_TC_BODY(sigchild_normal, tc)
208 switch ((child = fork())) {
213 atf_tc_fail("fork failed");
220 ATF_TC(sigchild_dump);
221 ATF_TC_HEAD(sigchild_dump, tc)
224 atf_tc_set_md_var(tc, "descr",
225 "Checks that signal trampoline correctly calls SIGCHLD handler "
226 "when child segfaults");
229 ATF_TC_BODY(sigchild_dump, tc)
238 switch ((child = fork())) {
241 *(volatile long *)0 = 0;
242 atf_tc_fail("Child did not segfault");
245 atf_tc_fail("fork failed");
252 ATF_TC(sigchild_kill);
253 ATF_TC_HEAD(sigchild_kill, tc)
256 atf_tc_set_md_var(tc, "descr",
257 "Checks that signal trampoline correctly calls SIGCHLD handler "
258 "when child is killed");
261 ATF_TC_BODY(sigchild_kill, tc)
270 switch ((child = fork())) {
276 atf_tc_fail("fork failed");
278 kill(child, SIGPIPE);
284 static sigjmp_buf sigfpe_flt_env;
286 sigfpe_flt_action(int signo, siginfo_t *info, void *ptr)
289 sig_debug(signo, info, (ucontext_t *)ptr);
291 if (fltdiv_signalled++ != 0)
292 atf_tc_fail("FPE handler called more than once");
294 ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
295 ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV);
296 ATF_REQUIRE_EQ(info->si_errno, 0);
298 siglongjmp(sigfpe_flt_env, 1);
302 ATF_TC_HEAD(sigfpe_flt, tc)
305 atf_tc_set_md_var(tc, "descr",
306 "Checks that signal trampoline correctly calls SIGFPE handler "
307 "for floating div-by-zero");
310 ATF_TC_BODY(sigfpe_flt, tc)
313 double d = strtod("0", NULL);
316 atf_tc_skip("Test does not run correctly under QEMU");
317 #if defined(__powerpc__)
318 atf_tc_skip("Test not valid on powerpc");
320 if (sigsetjmp(sigfpe_flt_env, 0) == 0) {
321 sa.sa_flags = SA_SIGINFO;
322 sa.sa_sigaction = sigfpe_flt_action;
323 sigemptyset(&sa.sa_mask);
324 sigaction(SIGFPE, &sa, NULL);
326 feenableexcept(FE_ALL_EXCEPT);
327 #elif defined(_FLOAT_IEEE754)
328 fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
330 printf("%g\n", 1 / d);
332 if (fltdiv_signalled == 0)
333 atf_tc_fail("FPE signal handler was not invoked");
336 static sigjmp_buf sigfpe_int_env;
338 sigfpe_int_action(int signo, siginfo_t *info, void *ptr)
341 sig_debug(signo, info, (ucontext_t *)ptr);
343 if (intdiv_signalled++ != 0)
344 atf_tc_fail("INTDIV handler called more than once");
346 ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
347 ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV);
348 atf_tc_expect_pass();
349 ATF_REQUIRE_EQ(info->si_errno, 0);
351 siglongjmp(sigfpe_int_env, 1);
355 ATF_TC_HEAD(sigfpe_int, tc)
358 atf_tc_set_md_var(tc, "descr",
359 "Checks that signal trampoline correctly calls SIGFPE handler "
360 "for integer div-by-zero (PR port-i386/43655)");
363 ATF_TC_BODY(sigfpe_int, tc)
366 long l = strtol("0", NULL, 10);
368 #if defined(__powerpc__)
369 atf_tc_skip("Test not valid on powerpc");
371 if (sigsetjmp(sigfpe_int_env, 0) == 0) {
372 sa.sa_flags = SA_SIGINFO;
373 sa.sa_sigaction = sigfpe_int_action;
374 sigemptyset(&sa.sa_mask);
375 sigaction(SIGFPE, &sa, NULL);
377 feenableexcept(FE_ALL_EXCEPT);
378 #elif defined(_FLOAT_IEEE754)
379 fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
381 printf("%ld\n", 1 / l);
383 if (intdiv_signalled == 0)
384 atf_tc_fail("FPE signal handler was not invoked");
388 sigsegv_action(int signo, siginfo_t *info, void *ptr)
391 sig_debug(signo, info, (ucontext_t *)ptr);
393 ATF_REQUIRE_EQ(info->si_signo, SIGSEGV);
394 ATF_REQUIRE_EQ(info->si_errno, 0);
395 ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR);
396 ATF_REQUIRE_EQ(info->si_addr, (void *)0);
403 ATF_TC_HEAD(sigsegv, tc)
406 atf_tc_set_md_var(tc, "descr",
407 "Checks that signal trampoline correctly calls SIGSEGV handler");
410 ATF_TC_BODY(sigsegv, tc)
414 sa.sa_flags = SA_SIGINFO;
415 sa.sa_sigaction = sigsegv_action;
416 sigemptyset(&sa.sa_mask);
417 sigaction(SIGSEGV, &sa, NULL);
419 *(volatile long *)0 = 0;
420 atf_tc_fail("Test did not fault as expected");
424 sigbus_action(int signo, siginfo_t *info, void *ptr)
427 printf("si_addr = %p\n", info->si_addr);
428 sig_debug(signo, info, (ucontext_t *)ptr);
430 ATF_REQUIRE_EQ(info->si_signo, SIGBUS);
431 ATF_REQUIRE_EQ(info->si_errno, 0);
432 ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN);
434 #if defined(__i386__) || defined(__x86_64__)
435 atf_tc_expect_fail("x86 architecture does not correctly "
436 "report the address where the unaligned access occured");
438 ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr);
444 ATF_TC(sigbus_adraln);
445 ATF_TC_HEAD(sigbus_adraln, tc)
448 atf_tc_set_md_var(tc, "descr",
449 "Checks that signal trampoline correctly calls SIGBUS handler "
450 "for invalid address alignment");
453 ATF_TC_BODY(sigbus_adraln, tc)
457 #if defined(__alpha__)
459 size_t len = sizeof(val);
460 rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0);
461 ATF_REQUIRE(rv == 0);
463 atf_tc_skip("SIGBUS signal not enabled for unaligned accesses");
466 sa.sa_flags = SA_SIGINFO;
467 sa.sa_sigaction = sigbus_action;
468 sigemptyset(&sa.sa_mask);
469 sigaction(SIGBUS, &sa, NULL);
471 /* Enable alignment checks for x86. 0x40000 is PSL_AC. */
472 #if defined(__i386__)
473 __asm__("pushf; orl $0x40000, (%esp); popf");
474 #elif defined(__amd64__)
475 __asm__("pushf; orl $0x40000, (%rsp); popf");
478 addr = calloc(2, sizeof(int));
479 ATF_REQUIRE(addr != NULL);
482 atf_tc_expect_fail("QEMU fails to trap unaligned accesses");
484 /* Force an unaligned access */
486 printf("now trying to access unaligned address %p\n", addr);
487 ATF_REQUIRE_EQ(*(volatile int *)addr, 0);
489 atf_tc_fail("Test did not fault as expected");
495 ATF_TP_ADD_TC(tp, sigalarm);
496 ATF_TP_ADD_TC(tp, sigchild_normal);
497 ATF_TP_ADD_TC(tp, sigchild_dump);
498 ATF_TP_ADD_TC(tp, sigchild_kill);
499 ATF_TP_ADD_TC(tp, sigfpe_flt);
500 ATF_TP_ADD_TC(tp, sigfpe_int);
501 ATF_TP_ADD_TC(tp, sigsegv);
502 ATF_TP_ADD_TC(tp, sigbus_adraln);
504 return atf_no_error();