Mr *_*nky 8 linux embedded cross-platform pthreads cross-compiling
我想在我的自定义Linux发行版上调试pthreads,但我遗漏了一些东西.我的主机是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
Run Code Online (Sandbox Code Playgroud)
我不认为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之间的任何不匹配.
这个:
dlopen failed on 'libthread_db.so.1' - /lib/libthread_db.so.1: undefined symbol: ps_lgetfpregs
GDB will not be able to debug pthreads.
Run Code Online (Sandbox Code Playgroud)
表示该libthread_db.so.1库无法ps_lgetfpregs在gdb中找到该符号。
为什么?
因为我使用Crosstoolg-NG和“ Build a static native gdb”选项构建了gdb,这会将-static选项添加到gcc。
本机gdb是使用-rdynamic选项构建的,它将用所有符号(甚至是未使用的符号)填充ELF文件中的.dynsym符号表。libread_db使用此符号表ps_lgetfpregs从gdb中查找。
但是-static剥去.dynsym从ELF文件表。
此时有两种选择:
编辑:
顺便说一句,这不能解释为什么Breakpad无法在我的目标上调试多线程应用程序。