我想在我的自定义 linux 发行版上调试 pthread,但我遗漏了一些东西。我的主机是 Ubuntu 12.04,我的目标是使用 crosstool-NG 交叉编译器工具集构建的 i486 定制嵌入式 Linux,操作系统的其余部分是使用 Buildroot 构建的。
我将列出事实:
我可以在我的目标上运行多线程应用程序
当我在目标上运行多线程应用程序时,Google Breakpad无法创建崩溃报告。当我在我的主机上运行它时,具有完全相同构建的 Breakpad 库的完全相同的应用程序将成功。
GDB 无法在我的目标上调试多线程应用程序。
例如
$./gdb -n -ex "thread apply all backtrace" ./a.out --pid 716
dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.
GNU gdb 6.8
我不认为 ps_lgetfpregs 是因为这个问题。
我的 crosstool 构建创建了 libthread_db.so 文件,并将其放在目标上。
我的 crosstool 构建为我的目标创建了 gdb,因此它应该与我在目标上运行的相同库链接。
如果我在我的主机上运行 gdb,针对我的测试应用程序,我会得到每个正在运行的线程的回溯。
我怀疑 Breakpad 的问题与 GDB 的问题有关,但我无法证实这一点。唯一的共同点是缺乏多线程调试。
我的主机和目标之间存在一些重要的差异,这使我无法在目标上调试 pthread。
有谁知道它是什么?
编辑:
来自 TI 的Denys Dmytriyenko说:
通常,GDB 不是很挑剔,您可以混合搭配不同版本的 gdb 和 gdbserver。但是,不幸的是,如果您需要调试多线程应用程序,则需要对特定 API 进行一些依赖...
例如,如果您没有为线程支持正确构建 GDB,这是您可能会看到的消息之一:
dlopen 在“libthread_db.so.1”上失败 - /lib/libthread_db.so.1:未定义符号:ps_lgetfpregs GDB 将无法调试 pthread。
请注意,此错误与我得到的错误相同,但他没有详细说明如何“正确”构建 GDB。
GDB FAQ说:
(Q) GDB 没有看到除了发生崩溃的线程之外的任何线程;或者当我设置断点时 SIGTRAP 会杀死我的程序。
(A) 这在 Linux 上经常发生,尤其是在嵌入式目标上。有两个常见的原因:
您正在使用 glibc,并且您已经剥离了 libpthread.so.0
libpthread.so.0 和 libthread_db.so.1 不匹配
GDB 本身不知道如何解码 glibc 维护的“线程控制块”,被认为是 glibc 私有实现细节。它使用 libthread_db.so.1(glibc 的一部分)来帮助它这样做。因此,libthread_db.so.1 和 libpthread.so.0 的版本和编译标志必须匹配。此外,libthread_db.so.1 要求某些非全局符号存在于 libpthread.so.0 中。
解决方案:使用 strip --strip-debug libpthread.so.0 代替 strip libpthread.so.0。
我尝试了一个未剥离的 libpthread.so.0,但它没有任何区别。我将调查 pthread 和 thread_db 之间的任何不匹配。