【问题标题】:What do I need to debug pthreads?我需要什么来调试 pthreads?
【发布时间】:2012-09-07 09:44:40
【问题描述】:

我想在我的自定义 linux 发行版上调试 pthread,但我遗漏了一些东西。我的主机是 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

我认为 ps_lgetfpregs 不是问题,因为 this

  • 我的 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 之间的任何不匹配。

【问题讨论】:

  • 你是不是同时玩着玩玩玩玩玩玩玩的?你肯定不喜欢为自己做事。
  • 哈哈哈,是的。欢迎来到嵌入式 Linux,没有什么是直截了当的,你必须对所有事情都有一点了解(但永远不足以真正胜任)。
  • 结果证明使用 -static 选项构建 gdb 会否定 -rdynamic 选项,该选项会阻止 thread_db 在静态 gdb 中查找符号。因此错误“未定义符号:ps_lgetfpregs”

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


【解决方案1】:

这个:

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

为什么?

因为我使用带有“构建静态原生 gdb”选项的 Crosstoolg-NG 构建 gdb,这会将 -static 选项添加到 gcc。

原生 gdb 是使用 -rdynamic 选项构建的,这会在 ELF 文件中的 .dynsym 符号表中填充所有符号,甚至是未使用的符号。 libread_db 使用此符号表从 gdb 中查找 ps_lgetfpregs

但是-static 会从 ELF 文件中删除 .dynsym 表。

此时有两种选择:

  1. 如果要调试线程,请勿构建静态原生 gdb。
  2. 构建静态 gdb 和静态 libthread_db(未测试)

编辑:

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

【讨论】:

  • 感谢您的提示。事实证明,当您使用“-fvisibility=hidden”时,您就像迷路一样,因为符号不会公开。
【解决方案2】:

不过...要使用 gdb 调试器,您需要使用 -g 选项编译代码。比如 gcc -g -c *.c.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多