2 Check that a fault signal handler gets the expected info
10 #include "tests/asm.h"
11 #include "tests/sys_mman.h"
20 static const struct test
*cur_test
;
24 static jmp_buf escape
;
26 #define BADADDR ((int *)0x1234)
28 #define FILESIZE (16*1024)
29 #define MAPSIZE (2*FILESIZE)
31 static char volatile *volatile mapping
;
33 static int testsig(int sig
, int want
)
36 fprintf(stderr
, " FAIL: expected signal %d, not %d\n", want
, sig
);
42 static int testcode(int code
, int want
)
45 fprintf(stderr
, " FAIL: expected si_code==%d, not %d\n", want
, code
);
51 static int testaddr(void *addr
, volatile void *want
)
54 fprintf(stderr
, " FAIL: expected si_addr==%p, not %p\n", want
, addr
);
61 static void handler(int sig
, siginfo_t
*si
, void *uc
)
65 ok
= ok
&& testsig(sig
, cur_test
->sig
);
66 ok
= ok
&& testcode(si
->si_code
, cur_test
->code
);
68 ok
= ok
&& testaddr(si
->si_addr
, cur_test
->addr
);
71 fprintf(stderr
, " PASS\n");
73 siglongjmp(escape
, ok
+ 1);
77 extern char test1_ill
;
80 asm volatile(VG_SYM(test1_ill
) ": ud2");
85 asm volatile ("int3");
90 asm volatile ("int $0x10");
96 asm volatile ("add $1, %0;"/* set OF */
98 : "=a" (a
) : "0" (0x7fffffff) : "cc");
103 static int limit
[2] = { 0, 10 };
105 asm volatile ("bound %0, %1" : : "r" (11), "m" (limit
[0]));
111 static const int sigs
[] = { SIGSEGV
, SIGILL
, SIGBUS
, SIGFPE
, SIGTRAP
};
114 sa
.sa_sigaction
= handler
;
115 sa
.sa_flags
= SA_SIGINFO
;
116 sigfillset(&sa
.sa_mask
);
118 for(i
= 0; i
< sizeof(sigs
)/sizeof(*sigs
); i
++)
119 sigaction(sigs
[i
], &sa
, NULL
);
121 fd
= open("faultstatus.tmp", O_CREAT
|O_TRUNC
|O_EXCL
, 0600);
126 unlink("faultstatus.tmp");
127 ftruncate(fd
, FILESIZE
);
129 mapping
= mmap(0, MAPSIZE
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
133 const struct test tests
[] = {
134 #define T(n, sig, code, addr) { test##n, sig, code, addr }
135 T(1, SIGILL
, ILL_ILLOPN
, &test1_ill
),
137 T(2, SIGTRAP
, 128, 0), /* TRAP_BRKPT? */
138 T(3, SIGSEGV
, 128, 0),
139 T(4, SIGSEGV
, 128, 0),
141 /* This is an expected failure - Valgrind
142 doesn't implement the BOUND instruction,
143 and so issues a SIGILL instead. */
144 T(5, SIGSEGV
, 128, 0),
148 for(i
= 0; i
< sizeof(tests
)/sizeof(*tests
); i
++) {
149 cur_test
= &tests
[i
];
151 if (sigsetjmp(escape
, 1) == 0) {
152 fprintf(stderr
, "Test %d: ", i
+1);
154 fprintf(stderr
, " FAIL: no fault, or handler returned\n");