configure.ac: Generalize glibc version check
[valgrind.git] / memcheck / tests / x86-linux / int3-x86.c
blob2a7fc643aaca2f9213cd104b0a0cb58e49b659f7
2 #undef _GNU_SOURCE
3 #define _GNU_SOURCE 1
5 #include <signal.h>
6 #include <stdio.h>
7 #include <sys/ucontext.h>
9 static char* eip_at_sig = NULL;
11 static void int_handler(int signum, siginfo_t *si, void *uc_arg)
13 ucontext_t *uc = (ucontext_t *)uc_arg;
14 /* Note that uc->uc_mcontext is an embedded struct, not a pointer */
15 mcontext_t *mc = &(uc->uc_mcontext);
16 void *pc = (void*)mc->gregs[REG_EIP];
17 printf("in int_handler, EIP is ...\n");
18 eip_at_sig = pc;
21 static void register_handler(int sig, void *handler)
23 struct sigaction sa;
24 sa.sa_flags = SA_RESTART | SA_SIGINFO;
25 sigfillset(&sa.sa_mask);
26 sa.sa_sigaction = handler;
27 sigaction(sig, &sa, NULL);
30 int main(void) {
31 char *intaddr = NULL;
32 puts("main");
33 register_handler(SIGTRAP, int_handler);
34 asm volatile(
35 "movl $zz_int, %%edx\n"
36 "mov %%edx, %0\n"
37 "zz_int:\n"
38 "int $3\n"
39 : /* no outputs */
40 : "m" (intaddr) /* input: address of var to store target addr to */
41 : /* clobbers */ "edx"
43 /* intaddr is the address of the int 3 insn. eip_at_sig is the PC
44 after the exception, which should be the next insn along.
45 Hence: */
46 if (intaddr != NULL && eip_at_sig != NULL
47 && eip_at_sig == intaddr+1)
48 printf("PASS\n");
49 else
50 printf("FAIL\n");
51 return 0;