符号与调试信息
报告里出现地址或未知符号,说明解析目标时找不到对应符号来源。符号分三类:业务程序自身的调试信息、它依赖的共享库符号、以及内核符号。三类来源的补齐方式各不相同,容器场景还要额外确认容器侧二进制与宿主内核符号是否分别就位。
基本信息
| 适用平台 | Linux(采集与解析工具链) |
|---|---|
| 检查手段 | 未知符号检索、构建标识列表、内核符号可见性参数 |
| 符号来源 | 调试信息包、程序自带符号、内核符号表 |
| 容器场景 | 容器侧二进制与宿主内核符号需分别处理 |
| 受限环境 | 符号可能被内核安全设置隐藏 |
典型使用场景
- 报告里大量条目显示为地址,无法判断热点函数。
- 容器内采集后解析失败,需要确认符号来自哪一侧。
- 核对被采样的二进制是否就是线上运行的那个版本。
- 第三方库符号缺失,需要安装对应的调试信息包。
- 受限环境中符号被隐藏,需要先确认安全设置。
核对
核对
perf report --stdio | grep -i unknown | head # 先统计未知符号的规模
cat /proc/sys/kernel/kptr_restrict # 内核符号可见性限制
cat /proc/sys/kernel/perf_event_paranoid # 采集权限限制
perf buildid-list | head # 采集到的构建标识,核对二进制版本
addr2line -e /opt/app/bin/server 0x1234 # 用地址反查源码行
readelf -n /opt/app/bin/server | grep -i build # 确认二进制构建标识三类符号来源
| 来源 | 补齐方式 | 常见坑 |
|---|---|---|
| 业务程序 | 安装带调试信息的构建产物 | 线上跑的是剥离符号的版本 |
| 共享库 | 安装发行版调试信息包 | 库版本与线上不一致 |
| 内核 | 配置内核符号可见性 | 安全设置隐藏符号却被当成工具缺陷 |
先确认构建标识与线上二进制一致,再补调试信息:版本对不上时符号看起来「补齐了」,实际对应的是另一份代码,更容易得出错误结论。
为排查方便放宽内核符号可见性与采集权限属于降低安全边界的操作,应在受限环境或排查窗口内进行,并记得恢复设置。