为跨平台 gdb-multiarch 调试加载 libthread_db 时出错
Error while loading libthread_db for cross-platform gdb-multiarch debugging
我有一台 x86 主机 运行 64 位 Linux 和 ARM 目标板 运行 32 位 Linux。我在主机上使用 gdb-multiarch
来调试从目标板上的多线程二进制文件 运行 生成的核心转储文件。调试似乎有效(至少是 bt
、info threads
等基本内容)。
但是,我在启动时看到与 libthread_db
相关的警告。我了解到您可以使用 set debug libthread-db 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
- 然后,我看到正在加载来自目标板的
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
- 最后,
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 提供的信息来构造更高级别的概念(活动线程等) .).
我有一台 x86 主机 运行 64 位 Linux 和 ARM 目标板 运行 32 位 Linux。我在主机上使用 gdb-multiarch
来调试从目标板上的多线程二进制文件 运行 生成的核心转储文件。调试似乎有效(至少是 bt
、info threads
等基本内容)。
但是,我在启动时看到与 libthread_db
相关的警告。我了解到您可以使用 set debug libthread-db 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
- 然后,我看到正在加载来自目标板的
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
- 最后,
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 提供的信息来构造更高级别的概念(活动线程等) .).