菜单
开源

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,或者您有可用的单独调试文件。您可以通过运行以下命令来实现:

bash
objcopy --only-keep-debug elf elf.debug
strip elf -o elf.stripped
objcopy --add-gnu-debuglink=elf.debug elf.stripped elf.debuglink

对于系统库,请确保已安装调试符号。例如,在 Ubuntu 上,您可以通过执行以下命令来安装 `libc` 的调试符号:

bash
apt install libc6-dbg

理解扁平的堆栈追踪

如果您的 Profile 数据显示许多浅层堆栈追踪(通常只有 1-2 帧深度),则您的二进制文件可能在编译时没有包含帧指针。

要使用帧指针编译代码,请在编译器选项中包含 `-fno-omit-frame-pointer` 标志。