/* -*- mode: C; c-basic-offset: 3; -*- */ #include <assert.h> #include <elf.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ptrace.h> #include <sys/types.h> #include <sys/uio.h> #include <sys/user.h> #include <sys/wait.h> static int err_out(const char *msg) { perror(msg); return 1; } static int non_empty(const char *buf, size_t len) { size_t i; int c = 0; volatile const char *p = buf; for (i = 0; i != len; i++) c |= p[i]; return c; } static int do_child(void) { if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) return err_out("ptrace traceme"); raise(SIGUSR1); return 0; } int main(void) { char buf[1024]; struct iovec iov; pid_t cpid, pid; int status; cpid = fork(); if (cpid == -1) return err_out("fork"); if (cpid == 0) return do_child(); pid = wait(&status); if (pid == -1) return err_out("wait"); /* Intentionally provide an uninitialized buffer to ptrace. */ iov.iov_len = sizeof(buf); iov.iov_base = buf; if (ptrace(0x4204, cpid, NT_PRSTATUS, &iov) == -1) return err_out("ptrace getregset"); assert(iov.iov_base == buf); assert(iov.iov_len > 0 && iov.iov_len < sizeof(buf)); /* We're assuming here that NT_PRSTATUS never contains all-zeros. */ assert(non_empty(buf, iov.iov_len)); puts("OK"); return 0; }