PageRenderTime 31ms CodeModel.GetById 16ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/src/ptracetest1.c

http://github.com/Eelis/geordi
C | 69 lines | 49 code | 16 blank | 4 comment | 11 complexity | 92405821e3bcd45a9b9b77ca56ad7dba MD5 | raw file
 1
 2#include <assert.h>
 3#include <sys/ptrace.h>
 4#include <linux/ptrace.h>
 5#include <sys/types.h>
 6#include <sys/wait.h>
 7#include <unistd.h>
 8#include <linux/user.h>
 9#include <sys/syscall.h> 
10#include <syscall.h>
11#include <sys/reg.h>
12#include <stdio.h>
13#include <stdlib.h>
14
15#ifdef __x86_64__
16#define SYSCALL_OFF (ORIG_RAX * 8)
17#else
18#define SYSCALL_OFF (ORIG_EAX * 4)
19#endif
20
21void checked (char const * const s, int const r) { if (r == -1) { perror(s); abort(); } }
22
23int main()
24{
25  pid_t const child = fork();
26
27  checked("fork", child);
28
29  if(child == 0)
30  {
31    checked("ptrace", ptrace(PTRACE_TRACEME, 0, NULL, NULL));
32    checked("execl", execl("/usr/bin/whoami", "whoami", NULL));
33  }
34  
35  int status;
36  checked("wait", wait(&status));
37  assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP);
38    // No way to know whether this SIGTRAP was caused by entry/exit, because we couldn't set PTRACE_O_TRACESYSGOOD until now (see ptracetest2.c).
39
40  printf("opaque trap passed\n");
41
42  checked("ptrace", ptrace(PTRACE_SETOPTIONS, child, NULL, PTRACE_O_TRACESYSGOOD));
43
44  for(;;)
45  {
46    checked("ptrace", ptrace(PTRACE_SYSCALL, child, NULL, NULL));
47
48    checked("wait", wait(&status));
49
50    if (WIFEXITED(status)) break;
51
52    if (WSTOPSIG(status) == (SIGTRAP | 0x80))
53    {
54      printf("syscall trap %ld\n", ptrace(PTRACE_PEEKUSER, child, SYSCALL_OFF, NULL));
55    }
56    else
57    {
58      assert(WSTOPSIG(status) == SIGTRAP);
59      printf("non-syscall trap\n");
60    }
61  }
62
63  return 0;
64}
65
66// On Eelis' machines, no syscall traps for execve are shown. On CoffeeBuzz' dual core machine, one syscall trap for execve is shown.
67// Conclusion: Using execve as "first SIGTRAP" foundation, one cannot know whether the first observed syscall trap is an entry or exit.
68
69// This testcase assumes that on syscall exit traps, ORIG_EAX/ORIG_RAX still holds the syscall number.