DF-5721 / probe_step.c
/* DF-5721 probe 2: PT_STEP over a `syscall` instruction (the cpu artifact * case filtered at trap.c:714-718). Must deliver SIGTRAP to the tracee, * never enter DDB. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <sys/types.h> #include <sys/ptrace.h> #include <sys/wait.h> int main(void) { pid_t pid = fork(); int st; if (pid == 0) { ptrace(PT_TRACE_ME, 0, (caddr_t)1, 0); kill(getpid(), SIGTRAP); /* stop #1 */ /* next instruction executed is `syscall` (getpid) while TF=1 */ __asm__ __volatile__( "movq $39, %%rax\n\t" /* SYS_getpid = 39 on DF x86_64 */ "syscall\n\t" "int3" /* stop #2: end marker */ : : : "rax", "rcx", "r11"); _exit(9); } wait(&st); printf("step: initial stop stopped=%d sig=%d\n", WIFSTOPPED(st), WSTOPSIG(st)); if (ptrace(PT_STEP, pid, (caddr_t)1, 0) < 0) { perror("PT_STEP"); exit(1); } wait(&st); if (WIFSTOPPED(st)) printf("step: after stepping over syscall: stopped=1 sig=%d\n", WSTOPSIG(st)); else if (WIFSIGNALED(st)) printf("step: child DIED sig=%d\n", WTERMSIG(st)); else printf("step: child exited %d\n", WEXITSTATUS(st)); ptrace(PT_CONTINUE, pid, (caddr_t)1, 0); wait(&st); printf("step: final stop/exitsig=%d (5=TRAP expected)\n", WIFSTOPPED(st) ? WSTOPSIG(st) : (WIFSIGNALED(st) ? WTERMSIG(st) : -WEXITSTATUS(st))); return 0; } |