给定程序计数器,在共享库中找到源代码行

Given program counter, find the source line in a shared library

我正在尝试在定制的 ARM 板上调试 Android 的 surfaceflinger 守护程序中的段错误。进程在转储调用堆栈和寄存器内容(包括程序计数器)之前崩溃。

通常我会使用 objdump 并搜索程序计数器。问题是调用堆栈的一部分在共享库中。在不使用 gdb 的情况下,如何将程序计数器与源文件中的一行相关联?即共享库指令的地址是否可以在没有运行程序的情况下确定?

您的程序(以及所有相关的共享库)需要使用调试信息进行编译(在 DWARF format), e.g. by passing some -g (or -g2 or -g3) flag to the GCC 编译器中编译它们。请注意,对于 GCC,此类调试选项可以与优化选项混合使用喜欢 -O2

那么您可能会使用像 addr2line, or perhaps libraries like libbacktrace 这样的实用程序。 FWIW,GCC 编译器本身(实际上是它的 cc1plus)使用那个 libbacktrace 库在 SIGSEGV 和其他终止信号(在编译器崩溃时)上打印有用的回溯。

顺便说一句,您可以(并且可能应该)启用 core(5) 转储并使用 gdb

对其进行 post 分析

请注意,由于 ASLR, a shared library is loaded (actually mmap(2)-ed) 在某些 "random" 页面。

阅读 Drepper 的 How to Write Shared Libraries 论文。

最简单的解决方案是将核心转储加载到 gdb 中并使用 info symbol <program counter address>,请参阅 。

您也可以使用 addr2line,但您必须在 addr2line 的参数中提供库起始地址,请参阅 How to map function address to function in *.so files