[C++] 生产环境进程不带符号表,用 perf 等最终生成的火焰图无法分析,怎么解呢?

2025 年 12 月 24 日
 Charlie17Li

背景

刚转到 C++,之前仅用 C++写过算法题,c++工程这块知之甚少。现在想分析进程的 cpu 消耗情况,于是准备采火焰图

问题

生产环境进程不带符号表,用 perf 采出来都是地址,火焰图上全是进程名字,看不到具体方法名怎么解呢?

当前临时的做法是重新编译了一个带符号表的版本,想知道生产环境采火焰图的最佳实践是啥呢?以及有没有大佬推荐一些性能分析的博客呢

2637 次点击
所在节点    程序员
8 条回复
yzwduck
2025 年 12 月 24 日
虽然工作里没接触过 Linux perf, 但遇到过类似的场景, 也需要解析程序的符号.

最好的办法是, 让生产环境有符号文件可查.

如果遇到难以复现的问题, 并且无法拿到那份特定程序的符号信息, 就会变得很麻烦, 但总有办法.

我目前的做法是:

* 找到复现问题用的, 没有符号的程序 A,
* 用类似的配置编译一份带符号的程序 B,
* 用 BinExport 配合 IDA Pro, Binary Ninja 或者 Ghidra 分别导出程序 A 和 B 的信息,
* 用 BinDiff 去匹配程序 A 和程序 B 里相似的函数, 生成一个 SQLite 数据库,
* 自己写脚本读取 SQLite 里程序 A 的符号信息, 填充到收集的原始资料里.
ysc3839
2025 年 12 月 24 日
neoblackcap
2025 年 12 月 25 日
据我了解,生产环境是采用流量回放的去调试。将生产环境一部分流量复制出来转发到你的测试环境中去(转发到带符号或者可调试的 C++程序中去),然后观察。
yanaraika
2025 年 12 月 25 日
你们这个发布流程不好。应该编译出来一个带全符号表的版本,然后生产环境部署一个/usr/bin/strip 掉调试信息的版本,这样可以直接在 perf 的时候手动指定带符号表的 binary
kkhaike
2025 年 12 月 25 日
正确做法是使用 -O2 -g 制作带符号表的生产环境二进制。。。可以直接上线这个带符号表的二进制,也可以上线 strip 后的二进制,然后调试的时候再替换就好
lixile
2025 年 12 月 25 日
要联合 cicd 一起来做 如果你们有的话 线上如果没有重现、重放条件 是不进行二进制替换的 只是补全调试信息罢了
首先就是默认的 release 版本加上-g
```
# 编译
g++ -O2 -g -fno-omit-frame-pointer -o app app.cpp

# 拆符号
objcopy --only-keep-debug app app.debug
strip --strip-debug app
# 符号文件再绑定
objcopy --add-gnu-debuglink=app.debug app

# perf

perf record -F 99 -g -- ./app

#手动指定 debug 路径
export PERF_BUILDID_DIR=/path/debugfile_dir
perf script > out.perf

```
tmaller
2025 年 12 月 26 日
编译-O2 -g, 编译后 eu-strip
swananan
2025 年 12 月 26 日
sym.tab 只能让你看到导出的函数,如果你还想看到类似于静态函数局部函数以及更细节的源码行号,得 -g ,生成 DWARF 调试信息来看。

可以直接生产环境提供具备这些信息的二进制,或者指定符号表和调试信息的文件在哪里,告知 perf 。

也可以对着 perf 火焰图里面的偏移,直接在自己有符号表和调试信息的环境,用 addr2line 命令,来换算出来,具体让 ai 写个脚本再处理一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/1181000

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX