5 from ctypes import c_ushort, c_int, c_ulonglong
9 print("Hit Ctrl-C to end.")
14 bpf_text="""#include <uapi/linux/ptrace.h>
15 #include <linux/sched.h>
17 typedef struct pdata_T {
19 char buf[TASK_COMM_LEN];
27 BPF_HASH(timestamp_b, u64);
28 BPF_HASH(timestamp_e, u64);
29 BPF_HASH(stats, u32, pdata_t, sizeof(pdata_t));
30 BPF_HASH(run_start, u32);
31 BPF_HASH(wait_start, u32);
35 int do_entry_dbus(struct pt_regs *ctx) {
38 pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
42 ts = bpf_ktime_get_ns() / 1000;
43 if(timestamp_b.lookup(&time) == 0){
44 timestamp_b.update(&time, &ts);
46 timestamp_e.update(&time, &ts);
48 pid = bpf_get_current_pid_tgid();
49 tsp = run_start.lookup(&pid);
50 run_start.delete(&pid);
51 wait_start.update(&pid, &ts);
59 pdata = *(stats.lookup_or_init(&pid, &new_pdata));
62 bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
63 stats.update(&pid, &pdata);
67 int do_return_dbus(struct pt_regs *ctx) {
70 pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
74 ts = bpf_ktime_get_ns() / 1000;
75 if(timestamp_b.lookup(&time) == 0){
76 timestamp_b.update(&time, &ts);
78 timestamp_e.update(&time, &ts);
80 pid = bpf_get_current_pid_tgid();
81 tsp = wait_start.lookup(&pid);
82 wait_start.delete(&pid);
83 run_start.update(&pid, &ts);
91 pdata = *(stats.lookup_or_init(&pid, &new_pdata));
93 bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
94 stats.update(&pid, &pdata);
98 int do_entry_glib(struct pt_regs *ctx) {
101 pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
105 ts = bpf_ktime_get_ns() / 1000;
106 if(timestamp_b.lookup(&time) == 0){
107 timestamp_b.update(&time, &ts);
109 timestamp_e.update(&time, &ts);
111 pid = bpf_get_current_pid_tgid();
112 tsp = run_start.lookup(&pid);
113 run_start.delete(&pid);
114 wait_start.update(&pid, &ts);
122 pdata = *(stats.lookup_or_init(&pid, &new_pdata));
124 pdata.usage += delta;
125 bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
126 stats.update(&pid, &pdata);
130 int do_return_glib(struct pt_regs *ctx) {
133 pdata_t new_pdata = {0, ' ', 0, 0, 0, 0, 0};
137 ts = bpf_ktime_get_ns() / 1000;
138 if(timestamp_b.lookup(&time) == 0){
139 timestamp_b.update(&time, &ts);
141 timestamp_e.update(&time, &ts);
143 pid = bpf_get_current_pid_tgid();
144 tsp = wait_start.lookup(&pid);
145 wait_start.delete(&pid);
146 run_start.update(&pid, &ts);
154 pdata = *(stats.lookup_or_init(&pid, &new_pdata));
155 pdata.gwait += delta;
156 bpf_get_current_comm(&(pdata.buf), sizeof(pdata.buf));
157 stats.update(&pid, &pdata);
162 b = BPF(text=bpf_text)
164 b.attach_uprobe(name="glib-2.0", sym="g_poll", fn_name="do_entry_glib")
165 b.attach_uprobe(name="dbus-1", sym="_dbus_poll", fn_name="do_entry_dbus")
167 b.attach_uretprobe(name="dbus-1", sym="_dbus_poll", fn_name="do_return_dbus")
168 b.attach_uretprobe(name="glib-2.0", sym="g_poll", fn_name="do_return_glib")
177 print ("%d : \n" % loop)
178 b["dist"].print_log2_hist("usecs")
181 timestamp = b["timestamp_e"]
183 for v in timestamp.values():
185 timestamp = b["timestamp_b"]
186 for v in timestamp.values():
188 #print("%d\n" % stats_t[0].pid)
189 print ("%10s %20s %10s %10s" % ("PID", "NAME", "DBUS", "GLIB"))
190 for v in sorted(stats_t.values(), key=lambda stats_t: stats_t.usage, reverse=True):
191 print("%10d %20s %10.6f %10.6f" % (v.pid, v.buf.encode('string-escape'), float(v.drun) / float(timeframe), float(v.grun) / float(timeframe)))