mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 16:36:21 +00:00
53 lines
1.3 KiB
C
53 lines
1.3 KiB
C
|
|
#undef _GNU_SOURCE
|
|
#define _GNU_SOURCE 1
|
|
|
|
#include <signal.h>
|
|
#include <stdio.h>
|
|
#include <sys/ucontext.h>
|
|
|
|
static char* eip_at_sig = NULL;
|
|
|
|
static void int_handler(int signum, siginfo_t *si, void *uc_arg)
|
|
{
|
|
ucontext_t *uc = (ucontext_t *)uc_arg;
|
|
/* Note that uc->uc_mcontext is an embedded struct, not a pointer */
|
|
mcontext_t *mc = &(uc->uc_mcontext);
|
|
void *pc = (void*)mc->gregs[REG_EIP];
|
|
printf("in int_handler, EIP is ...\n");
|
|
eip_at_sig = pc;
|
|
}
|
|
|
|
static void register_handler(int sig, void *handler)
|
|
{
|
|
struct sigaction sa;
|
|
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
|
sigfillset(&sa.sa_mask);
|
|
sa.sa_sigaction = handler;
|
|
sigaction(sig, &sa, NULL);
|
|
}
|
|
|
|
int main(void) {
|
|
char *intaddr = NULL;
|
|
puts("main");
|
|
register_handler(SIGTRAP, int_handler);
|
|
asm volatile(
|
|
"movl $zz_int, %%edx\n"
|
|
"mov %%edx, %0\n"
|
|
"zz_int:\n"
|
|
"int $3\n"
|
|
: /* no outputs */
|
|
: "m" (intaddr) /* input: address of var to store target addr to */
|
|
: /* clobbers */ "edx"
|
|
);
|
|
/* intaddr is the address of the int 3 insn. eip_at_sig is the PC
|
|
after the exception, which should be the next insn along.
|
|
Hence: */
|
|
if (intaddr != NULL && eip_at_sig != NULL
|
|
&& eip_at_sig == intaddr+1)
|
|
printf("PASS\n");
|
|
else
|
|
printf("FAIL\n");
|
|
return 0;
|
|
}
|