为跨平台 gdb-multiarch 调试加载 libthread_db 时出错

Error while loading libthread_db for cross-platform gdb-multiarch debugging

我有一台 x86 主机 运行 64 位 Linux 和 ARM 目标板 运行 32 位 Linux。我在主机上使用 gdb-multiarch 来调试从目标板上的多线程二进制文件 运行 生成的核心转储文件。调试似乎有效(至少是 btinfo threads 等基本内容)。

但是,我在启动时看到与 libthread_db 相关的警告。我了解到您可以使用 set debug libthread-db 1 获取一些额外的调试消息,这是我观察到的:

  1. 首先,我看到正在从主机加载 libthread_db。由于版本不匹配而失败,但在我看来这似乎是完全合理的。毕竟,为什么我的目标板上的 libpthread 与主机上的 libthread_db 兼容?
Trying host libthread_db library: libthread_db.so.1.
Host libthread_db.so.1 resolved to: /lib/x86_64-linux-gnu/libthread_db.so.1.
td_ta_new failed: versions of libpthread and libthread_db do not match
  1. 然后,我看到正在加载来自目标板的 libthread_db(我的主机上有 ARM 共享库)。它似乎失败了,因为 dlopen 需要一个 64 位共享库,但这对我来说没有意义,因为核心转储是从 32 位二进制文​​件生成的 .
Trying host libthread_db library: <snipped path>/lib/libthread_db.so.1.
dlopen failed:  <snipped path>/lib/libthread_db.so.1: wrong ELF class: ELFCLASS32.
thread_db_load_search returning 0
  1. 最后,gdb-multiarch 抱怨线程调试不可用。
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.

我做错了什么导致 libthread_db 无法正确加载?

What am I doing wrong that's preventing libthread_db from being loaded properly?

您没有做错任何事,但您需要有一个 x86_64 版本的 libthread_db.so.1,它与您的 32 位 ARM 目标上的 GLIBC 版本相同。

或者,您可以在主机上使用 32 位 GDB。该 GDB 将能够 dlopen <snipped path>/lib/libthread_db.so.1。由于您的目标是 32 位,因此在主机上使用 64 位 GDB 不会获得任何好处。

更新:

exactly what gdb is using libthread_db.so.1 for?

GDB 不知道 libpthread.so.0 的内部结构,因此它动态加载 libthread_db.so.1 并向 it 请求,例如枚举线程并将它们告诉 GDB。

显然要使此动态加载 (dlopen) 起作用,libthread_db.so.1 必须与 GDB 位数和体系结构相匹配。但是为了 libthread_db 了解 libpthread.so.0 的内部结构,它必须与目标使用的版本匹配 libpthread.so.0

您可能会问:libthread_db如何枚举目标进程中的线程?它不需要知道劣质(被调试)进程的内存内容吗?

为什么是的,它确实如此,并且它使用 GDB 执行低级读写。

也就是说,GDB 调用 libthread_db,它回调 GDB 以获取低级劣质内存和寄存器访问,然后使用 GDB 提供的信息来构造更高级别的概念(活动线程等) .).