如何使用perf工具按ELF段展示事件计数?(适配-ffunction-sections编译)
如何让perf report按ELF段显示事件计数
perf本身没有直接的内置选项让perf report直接将Symbol列替换为ELF段,但可以通过以下两种方式实现需求:
方法一:perf script + 自定义解析脚本
- 先正常录制perf数据:
perf record echo "hi" - 用
perf script导出原始事件数据:perf script > perf.data.txt - 编写脚本(比如awk/Python)完成地址到ELF段的映射与统计:
- 先通过
readelf -S <目标二进制文件>获取所有ELF段的起始、结束地址及段名,将这些信息存入地址范围-段名的映射表 - 遍历
perf script的输出,提取每个事件的IP地址,判断其所属的ELF段 - 累加每个段的事件计数,最终输出各段的统计结果
- 先通过
举个简单的awk脚本思路(适配x86_64二进制):
# 先提取段信息并初始化映射 BEGIN { # 替换为你的目标二进制路径 "readelf -S ./echo" | getline while ("readelf -S ./echo" | getline line) { if (match(line, /\[.*\] (\.[^ ]+) +PROGBITS +([0-9a-f]+) +([0-9a-f]+)/, arr)) { sec_name = arr[1] sec_start = strtonum("0x" arr[2]) sec_end = sec_start + strtonum("0x" arr[3]) sec_map[sec_start] = sec_name sec_end_map[sec_name] = sec_end } } } # 处理perf script输出的IP地址 /^echo/ { ip = strtonum("0x" $3) for (start in sec_map) { name = sec_map[start] if (ip >= start && ip < sec_end_map[name]) { count[name]++ break } } } # 最后输出统计结果 END { for (name in count) { printf "%-20s %d\n", name, count[name] } }
执行脚本的命令:
awk -f section_stats.awk perf.data.txt
方法二:利用perf report的原始数据导出
- 导出perf report的原始调试数据:
perf report -D > perf.debug.txt - 同样结合
readelf的段信息,编写脚本解析perf.debug.txt中的地址字段,映射到对应的ELF段并统计计数。这种方法能获取更详细的事件元数据,适合复杂场景。
针对你提到的-ffunction-sections编译场景,上述方法能准确将每个事件归属到对应的.text.<函数名>段,避免常规符号解析可能出现的问题,得到可靠的段级统计结果。
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

