我想debugging我的自定义Linux发行版上的pthreads,但我错过了一些东西。 我的主机是Ubuntu 12.04,我的目标是使用crosstool-NG交叉编译器工具集构build的i486定制embedded式Linux,其余的操作系统是使用Buildroot制作的。
我将列举事实:
我可以在我的目标上运行multithreading应用程序
当我在目标上运行multithreading应用程序时, Google Breakpad无法创build崩溃报告。 当我在我的主机上运行完全相同的应用程序与完全相同的构buildBreakpad库将成功。
GDB无法在我的目标上debuggingmultithreading应用程序。
例如
$./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构build了libthread_db.so文件,并将其放在目标上。
我的crosstool构build为我的目标创build了gdb,所以它应该与我在目标上运行的库相链接。
如果我在我的主机上运行gdb,对我的testing应用程序,我得到每个运行线程的回溯。
我怀疑Breakpad的问题与GDB的问题有关,但是我不能证实这一点。 唯一的共同点是缺乏multithreadingdebugging。
我的主机和目标之间有一些关键的区别阻止了我能够debugging目标上的pthreads。
有谁知道它是什么?
编辑:
TI的Denys Dmytriyenko表示:
通常情况下,GDB不是很挑剔,你可以混合使用不同版本的gdb和gdbserver。 但是,不幸的是,如果您需要debuggingmultithreading应用程序,那么对于特定的API有一些依赖关系…
例如,如果您没有为线程支持正确构buildGDB,则可能会看到以下消息之一:
dlopen在'libthread_db.so.1'上失败 – /lib/libthread_db.so.1:undefined symbol:ps_lgetfpregs GDB将无法debuggingpthreads。
请注意,这个错误与我所得到的错误是一样的,但他没有详细介绍如何正确地构buildGDB。
GDB常见问题解答说:
(Q)除了发生崩溃的线程外,GDB没有看到任何线程。 或SIGTRAP杀死我的程序,当我设置一个断点。
(A)这经常发生在Linux上,特别是在embedded式目标上。 有两个常见原因:
你正在使用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之间的任何不匹配。
这个:
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无法在我的目标上调试多线程应用程序。
只是一个虽然…要使用gdb调试器,你需要用-g选项编译你的代码。 例如,gcc -g -c * .c。