VMM: Sync halting GPCs and interrupt injection
[akaros.git] / tests / strace.c
1 /* Copyright (c) 2016 Google Inc., All Rights Reserved.
2  * Ron Minnich <rminnich@google.com>
3  * See LICENSE for details. */
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <parlib/parlib.h>
8 #include <unistd.h>
9 #include <signal.h>
10 #include <iplib/iplib.h>
11 #include <iplib/icmp.h>
12 #include <ctype.h>
13 #include <pthread.h>
14 #include <parlib/spinlock.h>
15 #include <parlib/timing.h>
16 #include <parlib/tsc-compat.h>
17 #include <parlib/printf-ext.h>
18 #include <benchutil/alarm.h>
19 #include <ndblib/ndb.h>
20 #include <fcntl.h>
21
22 #include <sys/types.h>
23 #include <sys/wait.h>
24
25 void usage(void)
26 {
27         fprintf(stderr, "usage: strace command [args...]\n");
28         exit(1);
29 }
30
31 void main(int argc, char **argv, char **envp)
32 {
33         int fd;
34         int pid;
35         int amt;
36         static char p[2 * MAX_PATH_LEN];
37         static char buf[16384];
38         struct syscall sysc;
39
40         if (argc < 2)
41                 usage();
42
43         pid = create_child_with_stdfds(argv[1], argc - 1, argv + 1, envp);
44         if (pid < 0) {
45                 perror("proc_create");
46                 exit(-1);
47         }
48         /* We need to wait on the child asynchronously.  If we hold a ref (as the
49          * parent), the child won't proc_free and that won't hangup/wake us from a
50          * read. */
51         syscall_async(&sysc, SYS_waitpid, pid, NULL, 0, 0, 0, 0);
52
53         snprintf(p, sizeof(p), "/proc/%d/ctl", pid);
54         fd = open(p, O_WRITE);
55         if (fd < 0) {
56                 fprintf(stderr, "open %s: %r\n", p);
57                 exit(1);
58         }
59
60         snprintf(p, sizeof(p), "straceall");
61         if (write(fd, p, strlen(p)) < strlen(p)) {
62                 fprintf(stderr, "write to ctl %s %d: %r\n", p, fd);
63                 exit(1);
64         }
65         close(fd);
66
67         snprintf(p, sizeof(p), "/proc/%d/strace", pid);
68         fd = open(p, O_READ);
69         if (fd < 0) {
70                 fprintf(stderr, "open %s: %r\n", p);
71                 exit(1);
72         }
73
74         /* now that we've set up the tracing, we can run the process.  isn't it
75          * great that the process doesn't immediately start when you make it? */
76         sys_proc_run(pid);
77
78         while ((amt = read(fd, buf, sizeof(buf))) > 0) {
79                 if (write(fileno(stderr), buf, amt) < amt) {
80                         fprintf(stderr, "Write to stdout: %r\n");
81                         exit(1);
82                 }
83         }
84         fprintf(stderr, "strace of PID %d: %r\n", pid);
85 }