eBPF 安装故障排除
了解如何排除和解决 eBPF 安装问题。
为解释型语言进行 Profiling
使用此实现对 Ruby、JavaScript 等解释型语言进行 Profiling 并不理想。这些语言中的 JIT 编译方法通常不是 ELF 文件格式,需要额外的步骤来进行 Profiling。例如,对 Java 使用 perf-map-agent 并启用帧指针。
解释型方法显示的是解释器函数的名称,而不是实际函数的名称。
未知符号故障排除
符号从以下各种来源提取,包括:
- ELF 文件中的 `.symtab` 和 `.dynsym` 段。
- 调试 ELF 文件中的 `.symtab` 和 `.dynsym` 段。
- Go 语言 ELF 文件中的 `.gopclntab` 段。
调试文件的搜索遵循 gdb 算法。例如,如果 profiler 需要查找 `/lib/x86_64-linux-gnu/libc.so.6` 的调试文件,该文件设置了 `.gnu_debuglink` 指向 `libc.so.6.debug`,并且构建 ID 为 `0123456789abcdef`。Profiler 会检查以下路径:
/usr/lib/debug/.build-id/01/0123456789abcdef.debug
/lib/x86_64-linux-gnu/libc.so.6.debug
/lib/x86_64-linux-gnu/.debug/libc.so.6.debug
/usr/lib/debug/lib/x86_64-linux-gnu/libc.so.6.debug
处理未知符号
您收集的 Profile 数据中出现未知符号,表明 profiler 无法访问追踪中给定地址相关的 ELF 文件。
这可能由以下几个原因引起:
- 进程已终止,导致 ELF 文件不可访问。
- ELF 文件损坏或未被识别为 ELF 文件。
- 堆栈追踪中的地址在 `/proc/pid/maps` 中没有对应的 ELF 文件条目。
解决未解析的符号
如果您只看到模块名称(例如 `/lib/x86_64-linux-gnu/libc.so.6`)而没有对应的函数名称,这表明符号无法映射到相应的函数名称。
这可能由以下几个原因引起:
- 二进制文件已被 stripping,导致 ELF 文件中没有 `.symtab`、`.dynsym` 或 `.gopclntab` 段。
- 调试文件丢失或无法找到。
要修复二进制文件的问题,请确保它们未被 stripping,或者您有可用的单独调试文件。您可以通过运行以下命令来实现:
objcopy --only-keep-debug elf elf.debug
strip elf -o elf.stripped
objcopy --add-gnu-debuglink=elf.debug elf.stripped elf.debuglink
对于系统库,请确保已安装调试符号。例如,在 Ubuntu 上,您可以通过执行以下命令来安装 `libc` 的调试符号:
apt install libc6-dbg
理解扁平的堆栈追踪
如果您的 Profile 数据显示许多浅层堆栈追踪(通常只有 1-2 帧深度),则您的二进制文件可能在编译时没有包含帧指针。
要使用帧指针编译代码,请在编译器选项中包含 `-fno-omit-frame-pointer` 标志。