|
1
|
#include <stdio.h>
|
|
2
|
#include <stdlib.h>
|
|
3
|
#include <sys/types.h>
|
|
4
|
#include <sys/stat.h>
|
|
5
|
#include <fcntl.h>
|
|
6
|
#include <unistd.h>
|
|
7
|
#include <string.h>
|
|
8
|
|
|
9
|
#define _STR(x) #x
|
|
10
|
#define STR(x) _STR(x)
|
|
11
|
#define MAX_PATH 256
|
|
12
|
|
|
13
|
const char *find_debugfs(void)
|
|
14
|
{
|
|
15
|
static char debugfs[MAX_PATH+1];
|
|
16
|
static int debugfs_found;
|
|
17
|
char type[100];
|
|
18
|
FILE *fp;
|
|
19
|
|
|
20
|
if (debugfs_found)
|
|
21
|
return debugfs;
|
|
22
|
|
|
23
|
if ((fp = fopen("/proc/mounts","r")) == NULL) {
|
|
24
|
perror("/proc/mounts");
|
|
25
|
return NULL;
|
|
26
|
}
|
|
27
|
|
|
28
|
while (fscanf(fp, "%*s %"
|
|
29
|
STR(MAX_PATH)
|
|
30
|
"s %99s %*s %*d %*d\n",
|
|
31
|
debugfs, type) == 2) {
|
|
32
|
if (strcmp(type, "debugfs") == 0)
|
|
33
|
break;
|
|
34
|
}
|
|
35
|
fclose(fp);
|
|
36
|
|
|
37
|
if (strcmp(type, "debugfs") != 0) {
|
|
38
|
fprintf(stderr, "debugfs not mounted");
|
|
39
|
return NULL;
|
|
40
|
}
|
|
41
|
|
|
42
|
debugfs_found = 1;
|
|
43
|
|
|
44
|
return debugfs;
|
|
45
|
}
|
|
46
|
|
|
47
|
const char *tracing_file(const char *file_name)
|
|
48
|
{
|
|
49
|
static char trace_file[MAX_PATH+1];
|
|
50
|
snprintf(trace_file, MAX_PATH, "%s/tracing/%s", find_debugfs(), file_name);
|
|
51
|
return trace_file;
|
|
52
|
}
|
|
53
|
|
|
54
|
int main (int argc, char **argv)
|
|
55
|
{
|
|
56
|
int fdt, fdp, fde, fdtrace;
|
|
57
|
int status;
|
|
58
|
char buf[1024];
|
|
59
|
ssize_t bytes;
|
|
60
|
|
|
61
|
if (argc < 2)
|
|
62
|
exit(-1);
|
|
63
|
|
|
64
|
fdt = open(tracing_file("current_tracer"), O_WRONLY);
|
|
65
|
fdp = open(tracing_file("set_ftrace_pid"), O_WRONLY);
|
|
66
|
fde = open(tracing_file("tracing_enabled"), O_WRONLY);
|
|
67
|
|
|
68
|
if (fdt < 0 || fdp < 0 || fde < 0) {
|
|
69
|
perror("open");
|
|
70
|
exit(-1);
|
|
71
|
}
|
|
72
|
|
|
73
|
write(fdt, "nop", 3);
|
|
74
|
|
|
75
|
if (fork() == 0) {
|
|
76
|
bytes = sprintf(buf, "%d\n", getpid());
|
|
77
|
write(fdp, buf, bytes);
|
|
78
|
|
|
79
|
write(fdt, argv[1], strlen(argv[1]));
|
|
80
|
write(fde, "1", 1);
|
|
81
|
|
|
82
|
execvp(argv[2], argv+2);
|
|
83
|
} else {
|
|
84
|
fprintf(stderr, "Waiting child\n");
|
|
85
|
wait(&status);
|
|
86
|
fprintf(stderr, "Child terminated, copying trace\n");
|
|
87
|
|
|
88
|
write(fde, "0", 1);
|
|
89
|
|
|
90
|
fdtrace = open(tracing_file("trace"), O_RDONLY);
|
|
91
|
|
|
92
|
while ((bytes = read(fdtrace, buf, sizeof(buf))) > 0)
|
|
93
|
write(STDOUT_FILENO, buf, bytes);
|
|
94
|
|
|
95
|
close(fdtrace);
|
|
96
|
|
|
97
|
write(fdt, "nop", 3);
|
|
98
|
|
|
99
|
}
|
|
100
|
|
|
101
|
close(fdt);
|
|
102
|
close(fde);
|
|
103
|
close(fdp);
|
|
104
|
return 0;
|
|
105
|
}
|