我需要什么来调试pthreads?

时间:2012-09-07 09:44:40

标签: linux embedded pthreads cross-platform cross-compiling

我想在我的自定义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的

Denys Dmytriyenko说:

  

通常,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之间的任何不匹配。

2 个答案:

答案 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表。

此时有两种选择:

  1. 如果要调试线程,请不要构建静态本机gdb。
  2. 构建静态gdb和静态libthread_db(未测试)
  3. 编辑:

    顺便说一句,这并不能解释为什么Breakpad无法在我的目标上调试多线程应用程序。

答案 1 :(得分:0)

只是一个...要使用gdb调试器,您需要使用-g选项编译代码。例如,gcc -g -c * .c。