使用uprobe进行函数调用追踪是否会产生显著性能开销?
uprobe函数调用追踪的开销疑问
我刚开始学习eBPF,通过libbpf项目使用uprobe进行函数调用追踪。基于uprobe.c示例添加高分辨率时钟,测量挂载uprobe前后函数调用的开销。所有代码均以-O2编译。
关键代码片段
uprobe_target.cpp
int __attribute__ ((noinline)) uprobed_add(int a, int b) { return a + b; } int main(int argc, char **argv) { using namespace std::chrono; high_resolution_clock::time_point t1, t2; printf("uprobed_add = %lu\n", &uprobed_add); for (int i = 0; ; i++) { t1 = high_resolution_clock::now(); auto s = uprobed_add(i, i + 1); t2 = high_resolution_clock::now(); printf("%ld,\t#%d\n", duration_cast<nanoseconds>(t2 - t1), s); std::this_thread::sleep_for(std::chrono::seconds(3)); } }
uprobe.bpf.c
SEC("uprobe") int BPF_KPROBE(uprobe_add, int a, int b) { bpf_printk("uprobed_add ENTRY: a = %d, b = %d", a, b); return 0; } SEC("uretprobe") int BPF_KRETPROBE(uretprobe_add, int ret) { bpf_printk("uprobed_add EXIT: return = %d", ret); return 0; }
uprobe.c(挂载逻辑)
uprobe_offset = get_uprobe_offset(&uprobed_add_addr); /* Attach tracepoint handler */ skel->links.uprobe_add = bpf_program__attach_uprobe(skel->progs.uprobe_add, false /* not uretprobe */, -1 /* self pid */, "compiled_uprobe_target", uprobe_offset); skel->links.uretprobe_add = bpf_program__attach_uprobe(skel->progs.uretprobe_add, true /* uretprobe */, -1 /* any pid */, "compiled_uprobe_target", uprobe_offset); printf("Successfully started! Please run `sudo cat /sys/kernel/debug/tracing/trace_pipe` " "to see output of the BPF programs.\n");
测试结果
BPF钩子可正常挂载,能从/sys/kernel/debug/tracing/trace_pipe中看到类似bpf_trace_printk: uprobed_add ENTRY: a = 184, b = 185的输出。但挂载钩子前后,uprobed_add的调用速度慢了50倍:
- 挂载前
48, #467 35, #469 56, #471 64, #473 53, #475 40, #477
- 挂载后
11573, #19237 12242, #19239 10274, #19241 12566, #19243 12360, #19245 11727, #19247
我起初认为是钩子中的bpf_printk导致开销,但注释掉打印语句后耗时无明显变化。还通过sysfs接口的uprobe做了另一实验,结果类似:启用追踪点后,单次调用耗时立即跃升至10000ns以上。
echo 'p:enter_add /fsx/src/libbpf-bootstrap/examples/c/c.out:<uprobed_add_address>' >> /sys/kernel/debug/tracing/uprobe_events echo 1 > /sys/kernel/debug/tracing/events/uprobes/enter_add/enable
请问这是否是使用uprobe进行调用追踪的固有开销?
内容的提问来源于stack exchange,提问作者Ji Miao
相关产品推荐
相关产品推荐

