-
Notifications
You must be signed in to change notification settings - Fork 1
/
print_commands.py
executable file
·69 lines (60 loc) · 1.64 KB
/
print_commands.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/python3
from bcc import BPF, USDT
import sys
if len(sys.argv) < 2:
print("Need to pass along pid")
exit()
text = """
#include <linux/ptrace.h>
struct timing_t {
char buf[256];
u64 delta;
};
BPF_HASH(invoc_times, const void*);
BPF_PERF_OUTPUT(timings);
int start_command(struct pt_regs *ctx) {
u64 ts = bpf_ktime_get_ns();
const void* opCtx = NULL;
bpf_usdt_readarg(4, ctx, &opCtx);
if(opCtx)
invoc_times.update(&opCtx, &ts);
return 0;
}
int end_command(struct pt_regs *ctx) {
u64 ts, *tsp, delta;
const void* opCtx = NULL;
bpf_usdt_readarg(4, ctx, &opCtx);
tsp = invoc_times.lookup(&opCtx);
if(tsp) {
delta = bpf_ktime_get_ns() - *tsp;
char* name;
bpf_usdt_readarg(2, ctx, &name);
struct timing_t result;
result.delta = delta;
bpf_probe_read(&result.buf, sizeof(result.buf), name);
timings.perf_submit(ctx, &result, sizeof(result));
invoc_times.delete(&opCtx);
}
return 0;
}
"""
print(text)
pid = sys.argv[1]
print(int(pid))
pid = int(pid)
time_start = USDT(pid=pid)
time_start.enable_probe(probe="commandStart", fn_name="start_command")
time_end = USDT(pid=pid)
time_end.enable_probe(probe="commandEnd", fn_name="end_command")
b = BPF(text=text, usdt_contexts=[time_start, time_end])
def print_command(cpu, data, size):
event = b["timings"].event(data)
name = str(event.buf, 'utf-8')
print('{}\t{}'.format(name, event.delta))
b["timings"].open_perf_buffer(print_command)
print("Commands and length of completion in ns:")
while 1:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()