我想在我的自定义Linux发行版上调试pthreads,但我遗漏了一些东西。我的主机是Ubuntu 12.04,我的目标是使用crosstool-NG交叉编译工具集构建的i486自定义嵌入式Linux,其余的操作系统是用Buildroot制作的。
我将列出事实:
我可以在目标
Google Breakpad无法创建崩溃报告。当我在主机上运行时,完全相同的应用程序与完全相同的Breakpad库构建将成功。
GDB无法调试目标上的多线程应用程序。
e.g。
$./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
由于this,我认为ps_lgetfpregs不是问题。
我的crosstool构建创建了libthread_db.so文件,并将其放在目标上。
我的crosstool构建为我的目标创建了gdb,因此它应该与我在目标上运行的相同库链接。
如果我在我的主机上运行gdb,对我的测试应用程序,我得到每个正在运行的线程的回溯。
我怀疑Breakpad的问题与GDB的问题有关,但我无法证实这一点。唯一的共同点是缺少多线程调试。
我的主机和目标之间存在一些重要的区别,使我无法在目标上调试pthread。
有谁知道它是什么?
编辑:
TI的通常,GDB不是很挑剔,你可以混合和匹配不同的 gdb和gdbserver的版本。但是,不幸的是,如果你需要 调试多线程应用程序,有一些特定的依赖项 的API ...
例如,如果您没有,这是您可能会看到的消息之一 为线程支持正确构建GDB:
dlopen'libthread_db.so.1'失败 - /lib/libthread_db.so.1: 未定义的符号:ps_lgetfpregs GDB将无法调试 并行线程。
请注意,此错误与我获得的错误相同,但他没有详细介绍如何“正确”构建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之间的任何不匹配。
答案 0 :(得分:3)
此:
dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.
表示libthread_db.so.1
库无法在gdb中找到符号ps_lgetfpregs
。
为什么?
因为我使用Crosstoolg-NG使用“构建静态本机gdb”选项构建gdb,这会将-static
选项添加到gcc。
本机gdb使用-rdynamic
选项构建,这将使用所有符号填充ELF文件中的.dynsym符号表,甚至是未使用的符号。 libread_db使用此符号表从gdb中查找ps_lgetfpregs
。
但-static
从ELF文件中删除了.dynsym
表。
此时有两种选择:
编辑:
顺便说一句,这并不能解释为什么Breakpad无法在我的目标上调试多线程应用程序。
答案 1 :(得分:0)
只是一个...要使用gdb调试器,您需要使用-g选项编译代码。例如,gcc -g -c * .c。