Home | History | Annotate | Download | only in linux
      1 /* -*- mode: C; c-basic-offset: 3; -*- */
      2 
      3 #include <assert.h>
      4 #include <elf.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <unistd.h>
      9 
     10 #include <sys/ptrace.h>
     11 #include <sys/types.h>
     12 #include <sys/uio.h>
     13 #include <sys/user.h>
     14 #include <sys/wait.h>
     15 
     16 static int
     17 err_out(const char *msg)
     18 {
     19    perror(msg);
     20    return 1;
     21 }
     22 
     23 static int
     24 non_empty(const char *buf, size_t len)
     25 {
     26    size_t i;
     27    int c = 0;
     28    volatile const char *p = buf;
     29 
     30    for (i = 0; i != len; i++)
     31       c |= p[i];
     32    return c;
     33 }
     34 
     35 static int
     36 do_child(void)
     37 {
     38    if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1)
     39       return err_out("ptrace traceme");
     40    raise(SIGUSR1);
     41    return 0;
     42 }
     43 
     44 int
     45 main(void)
     46 {
     47    char buf[1024];
     48    struct iovec iov;
     49    pid_t cpid, pid;
     50    int status;
     51 
     52    cpid = fork();
     53    if (cpid == -1)
     54       return err_out("fork");
     55    if (cpid == 0)
     56       return do_child();
     57 
     58    pid = wait(&status);
     59    if (pid == -1)
     60       return err_out("wait");
     61 
     62    /* Intentionally provide an uninitialized buffer to ptrace. */
     63    iov.iov_len = sizeof(buf);
     64    iov.iov_base = buf;
     65    if (ptrace(0x4204, cpid, NT_PRSTATUS, &iov) == -1)
     66       return err_out("ptrace getregset");
     67 
     68    assert(iov.iov_base == buf);
     69    assert(iov.iov_len > 0 && iov.iov_len < sizeof(buf));
     70 
     71    /* We're assuming here that NT_PRSTATUS never contains
     72       all-zeros. */
     73    assert(non_empty(buf, iov.iov_len));
     74    puts("OK");
     75    return 0;
     76 }
     77