【发布时间】: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