You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

perf工具如何利用eh_frame实现无帧指针下的调用栈回溯?

无帧指针程序中基于perf的栈回溯实现疑问

背景与尝试

我正在学习如何在无帧指针的程序中打印调用栈,目前已经能借助ELF文件里的DWARF eh_frame 段实现栈回溯,也完成了ELF文件的分析测试。现在想了解如何通过perf_event_open进行采样并实现栈回溯。

我尝试编写了如下代码:

attr.type=PERF_TYPE_SOFTWARE;
attr.config=PERF_COUNT_SW_CPU_CLOCK;
attr.sample_period=100000;
attr.sample_type=PERF_SAMPLE_CALLCHAIN;
int fd=perf_event_open(&attr,0,-1,-1,0);
...

但遇到了问题:由于perf是异步写入采样数据,我们异步读取时,无帧指针情况下Linux内核仅返回一个栈帧(有帧指针时会返回多个),这时候再想用eh_frame回溯栈已经太晚,程序可能已经退出。

perf工具的有效测试

于是我用perf的--call-graph dwarf选项做了测试:

perf record --call-graph dwarf -p PID
perf report --call-graph --stdio -G

它能正确显示我用-fomit-frame-pointer编译的测试程序的调用栈。

核心疑问与跟踪结果

我的疑问是:它是如何实现的?我通过strace跟踪perf的调用:

# strace perf record --call-graph dwarf -p PID

perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_DUMMY, sample_period=0, sample_type=0, read_format=0, watermark=1, precise_ip=0 /* arbitrary skid */, sample_id_all=1, bpf_event=1,...}, 1, 63, -1, PERF_FLAG_FD_CLOEXEC) = 132

发现它并没有设置sample_type为PERF_SAMPLE_CALLCHAIN,那它是如何获取栈信息的?我知道perf使用libunwind进行回溯,但不清楚触发机制——比如前文提到的,内核仅返回一个PC(程序计数器)时,perf是如何完成栈回溯的?

内容的提问来源于stack exchange,提问作者Nail Jay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:22:36