我会列出事实:
>我可以在目标上运行多线程应用程序
> 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
由于this,我认为ps_lgetfpregs不是问题.
>我的crosstool构建创建了libthread_db.so文件,并将其放在目标上.
>我的crosstool构建为我的目标创建了gdb,因此它应该与我在目标上运行的相同库链接.
>如果我在我的主机上运行gdb,对我的测试应用程序,我会得到每个正在运行的线程的回溯.
我怀疑Breakpad的问题与GDB的问题有关,但我无法证实这一点.唯一的共同点是缺少多线程调试.
我的主机和目标之间存在一些重要的区别,使我无法在目标上调试pthread.
有谁知道它是什么?
编辑:
TI的Denys Dmytriyenko说:
Normally,GDB is not very picky and you can mix and match different
versions of gdb and gdbserver. But,unfortunately,if you need to
debug multi-threaded apps,there are some dependencies for specific
APIs…For example,this is one of the messages you may see if you didn’t
build GDB properly for the thread support:dlopen Failed on ‘libthread_db.so.1’ – /lib/libthread_db.so.1:
undefined symbol: ps_lgetfpregs GDB will not be able to debug
pthreads.
请注意,此错误与我获得的错误相同,但他没有详细介绍如何“正确”构建GDB.
并且GDB FAQ说:
(Q) GDB does not see any threads besides the one in which crash occurred;
or SIGTRAP kills my program when I set a breakpoint.(A) This frequently
happen on Linux,especially on embedded targets. There are two common
causes:
you are using glibc,and you have stripped libpthread.so.0
mismatch between libpthread.so.0 and libthread_db.so.1
GDB itself does
not know how to decode “thread control blocks” maintained by glibc and
considered to be glibc private implementation detail. It uses
libthread_db.so.1 (part of glibc) to help it do so. Therefore,
libthread_db.so.1 and libpthread.so.0 must match in version and
compilation flags. In addition,libthread_db.so.1 requires certain
non-global symbols to be present in libpthread.so.0.Solution: use
strip –strip-debug libpthread.so.0 instead of 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表.
此时有两种选择:
>如果要调试线程,请不要构建静态本机gdb.
>构建静态gdb和静态libthread_db(未测试)
编辑:
顺便说一下,这并不能解释为什么Breakpad无法在我的目标上调试多线程应用程序.