1432c899773f4776d75ef6b43960bd77a697c77f
[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         char *prog_name = argv[1];
40
41
42         if (argc < 2)
43                 usage();
44         if ((*argv[1] != '/') && (*argv[1] != '.')) {
45                 snprintf(p, sizeof(p), "/bin/%s", argv[1]);
46                 prog_name = p;
47         }
48
49         pid = sys_proc_create(prog_name, strlen(prog_name), argv + 1, envp,
50                               PROC_DUP_FGRP);
51         if (pid < 0) {
52                 perror("proc_create");
53                 exit(-1);
54         }
55         /* We need to wait on the child asynchronously.  If we hold a ref (as the
56          * parent), the child won't proc_free and that won't hangup/wake us from a
57          * read. */
58         syscall_async(&sysc, SYS_waitpid, pid, NULL, 0, 0, 0, 0);
59
60         snprintf(p, sizeof(p), "/proc/%d/ctl", pid);
61         fd = open(p, O_WRITE);
62         if (fd < 0) {
63                 fprintf(stderr, "open %s: %r\n", p);
64                 exit(1);
65         }
66
67         snprintf(p, sizeof(p), "straceall");
68         if (write(fd, p, strlen(p)) < strlen(p)) {
69                 fprintf(stderr, "write to ctl %s %d: %r\n", p, fd);
70                 exit(1);
71         }
72         close(fd);
73
74         snprintf(p, sizeof(p), "/proc/%d/strace", pid);
75         fd = open(p, O_READ);
76         if (fd < 0) {
77                 fprintf(stderr, "open %s: %r\n", p);
78                 exit(1);
79         }
80
81         /* now that we've set up the tracing, we can run the process.  isn't it
82          * great that the process doesn't immediately start when you make it? */
83         sys_proc_run(pid);
84
85         while ((amt = read(fd, buf, sizeof(buf))) > 0) {
86                 if (write(1, buf, amt) < amt) {
87                         fprintf(stderr, "Write to stdout: %r\n");
88                         exit(1);
89                 }
90         }
91         if ((amt < 0) && (errno != ESRCH))
92                 fprintf(stderr, "Read fd %d for %s: %r\n", fd, p);
93 }