如何更新我的 libthread_db 共享库以匹配 libpthread 共享库?
How do I update my libthread_db shared library so as to match libpthread shared library?
我正在使用 CentOS。我没有搭建服务器,环境比较旧
我尝试调试多线程服务器程序,但出现了一些错误。
Starting program: ./battle
Trying host libthread_db library: libthread_db.so.1.
Host libthread_db.so.1 resolved to: /lib64/libthread_db.so.1.
td_ta_new failed: application not linked with libthread
thread_db_load_search returning 0
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Trying host libthread_db library: libthread_db.so.1.
Host libthread_db.so.1 resolved to: /lib64/libthread_db.so.1.
td_ta_new failed: versions of libpthread and libthread_db do not match
Trying host libthread_db library: /lib64/libthread_db.so.1.
td_ta_new failed: versions of libpthread and libthread_db do not match
thread_db_load_search returning 0
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
然后我意识到问题是我 link 的 libpthread
共享库的版本与 gdb
使用的 libthread_db
共享库的版本不匹配调试时。
我阅读了这 2 个相关问题 Unable to Debug Multi-Threaded Application with gdb, GDB debugging warnings .
然后我试图通过使用file
命令找出每个版本是什么(请告诉我使用file
检查差异是否正确.不管怎样,我发现了一些不同。)
ldd battle
linux-vdso.so.1 (0x00007fffcafff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f390c675000)
.........
ls -l libpthread*
-rwxr-xr-x 1 root root 143280 Apr 9 2019 libpthread-2.12.so
-rwxr-xr-x 1 root root 806517 Dec 2 2018 libpthread-2.17.so
lrwxrwxrwx 1 root root 18 Jul 29 07:35 libpthread.so.0 -> libpthread-2.17.so
ls -l libthread_db*
-rwxr-xr-x 1 root root 34488 Apr 9 2019 libthread_db-1.0.so
lrwxrwxrwx 1 root root 19 Jul 29 07:35 libthread_db.so.1 -> libthread_db-1.0.so
file libpthread-2.17.so
libpthread-2.17.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped
file libthread_db-1.0.so
libthread_db-1.0.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
file libpthread-2.12.so
libpthread-2.12.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
所以我的程序被link编辑为libpthread-2.17.so
,for GNU/Linux 2.6.16
,gdb
使用libthread_db-1.0.so
,[=22] =], 不匹配? (好吧,我不确定是否可以根据这些信息比较它们,我可以吗?)
是不是说现在我需要下载一个libthread_db-1.0.so
给for GNU/Linux 2.6.16
和link libthread_db.so.1
? 我可以从哪里下载它?
对了,我也觉得奇怪,我服务器上的libpthread-2.17.so
和libpthread-2.12.so
,2.17 > 2.12
,前者应该是较新的版本。但它适用于较低的 Linux 版本 (2.6.16
),也许有人只是复制它并重命名文件?我不知道。 :(
您的问题与您已经找到的两个答案完全相同:有人在您的系统上安装了 GLIBC-2.17(最初可能有 GLIBC-2.12),但未能安装匹配 libthread_db.so.1
。
file
的输出——GNU/Linux 2.6.18
是转移注意力并且无关紧要。
好消息是更新 libpthread_db
是 risk-free —— 如果你搞砸了,最坏的情况是 GDB 不能用于 multi-threaded 程序,但是因为这就是目前的状态,你不能让它变得更糟了。
但你应该可以做得更好:
- 下载 GLIBC-2.17 源代码,配置并构建它(但不要
make install
,否则您的系统可能会变砖)。
- 作为构建的一部分,现在应该存在
build/nptl_db/libthread_db.so.1
- 通过使用
set libthread-db-search-path /path/to/build/nptl_db
将 GDB 指向它并尝试再次调试您的程序来测试它。
如果可行,您可以用刚构建的 non-working /lib64/libthread_db.so.1
覆盖。
更新:
Is there any command I can use to grab some version information of these shared library files?
对于libpthread*.so.0
,这很简单:
gdb -q /lib/x86_64-linux-gnu/libpthread.so.0
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...
(gdb) x/s nptl_version
0x16037 <nptl_version>: "2.30"
对于 libthread_db.so.1
来说要困难得多:你需要反汇编 td_ta_new
,然后寻找 memcmp
调用,它可以被内联:
gdb -q /lib/x86_64-linux-gnu/libthread_db.so.1
Reading symbols from /lib/x86_64-linux-gnu/libthread_db.so.1...
(gdb) disas td_ta_new
Dump of assembler code for function td_ta_new:
0x0000000000002270 <+0>: push %r13
0x0000000000002272 <+2>: push %r12
0x0000000000002274 <+4>: push %rbp
0x0000000000002275 <+5>: mov %rsi,%rbp
...
0x00000000000022d6 <+102>: callq 0x2110 <ps_pdread@plt>
0x00000000000022db <+107>: mov %eax,%r12d
0x00000000000022de <+110>: test %eax,%eax
0x00000000000022e0 <+112>: jne 0x2318 <td_ta_new+168>
0x00000000000022e2 <+114>: cmpl [=11=]x30332e32,0x13(%rsp)
0x00000000000022ea <+122>: je 0x2340 <td_ta_new+208>
0x00000000000022ec <+124>: mov [=11=]x16,%r12d
0x00000000000022f2 <+130>: mov 0x18(%rsp),%rax
0x00000000000022f7 <+135>: xor %fs:0x28,%rax
0x0000000000002300 <+144>: jne 0x2388 <td_ta_new+280>
0x0000000000002306 <+150>: add [=11=]x28,%rsp
0x000000000000230a <+154>: mov %r12d,%eax
0x000000000000230d <+157>: pop %rbx
0x000000000000230e <+158>: pop %rbp
0x000000000000230f <+159>: pop %r12
0x0000000000002311 <+161>: pop %r13
0x0000000000002313 <+163>: retq
...
此处,地址 0x022e2
是对 memcmp("2.30", <data-read-from-nptl_version>, 5)
.
的内联调用
我正在使用 CentOS。我没有搭建服务器,环境比较旧
我尝试调试多线程服务器程序,但出现了一些错误。
Starting program: ./battle
Trying host libthread_db library: libthread_db.so.1.
Host libthread_db.so.1 resolved to: /lib64/libthread_db.so.1.
td_ta_new failed: application not linked with libthread
thread_db_load_search returning 0
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Trying host libthread_db library: libthread_db.so.1.
Host libthread_db.so.1 resolved to: /lib64/libthread_db.so.1.
td_ta_new failed: versions of libpthread and libthread_db do not match
Trying host libthread_db library: /lib64/libthread_db.so.1.
td_ta_new failed: versions of libpthread and libthread_db do not match
thread_db_load_search returning 0
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
然后我意识到问题是我 link 的 libpthread
共享库的版本与 gdb
使用的 libthread_db
共享库的版本不匹配调试时。
我阅读了这 2 个相关问题 Unable to Debug Multi-Threaded Application with gdb, GDB debugging warnings .
然后我试图通过使用file
命令找出每个版本是什么(请告诉我使用file
检查差异是否正确.不管怎样,我发现了一些不同。)
ldd battle
linux-vdso.so.1 (0x00007fffcafff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f390c675000)
.........
ls -l libpthread*
-rwxr-xr-x 1 root root 143280 Apr 9 2019 libpthread-2.12.so
-rwxr-xr-x 1 root root 806517 Dec 2 2018 libpthread-2.17.so
lrwxrwxrwx 1 root root 18 Jul 29 07:35 libpthread.so.0 -> libpthread-2.17.so
ls -l libthread_db*
-rwxr-xr-x 1 root root 34488 Apr 9 2019 libthread_db-1.0.so
lrwxrwxrwx 1 root root 19 Jul 29 07:35 libthread_db.so.1 -> libthread_db-1.0.so
file libpthread-2.17.so
libpthread-2.17.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped
file libthread_db-1.0.so
libthread_db-1.0.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
file libpthread-2.12.so
libpthread-2.12.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
所以我的程序被link编辑为libpthread-2.17.so
,for GNU/Linux 2.6.16
,gdb
使用libthread_db-1.0.so
,[=22] =], 不匹配? (好吧,我不确定是否可以根据这些信息比较它们,我可以吗?)
是不是说现在我需要下载一个libthread_db-1.0.so
给for GNU/Linux 2.6.16
和link libthread_db.so.1
? 我可以从哪里下载它?
对了,我也觉得奇怪,我服务器上的libpthread-2.17.so
和libpthread-2.12.so
,2.17 > 2.12
,前者应该是较新的版本。但它适用于较低的 Linux 版本 (2.6.16
),也许有人只是复制它并重命名文件?我不知道。 :(
您的问题与您已经找到的两个答案完全相同:有人在您的系统上安装了 GLIBC-2.17(最初可能有 GLIBC-2.12),但未能安装匹配 libthread_db.so.1
。
file
的输出——GNU/Linux 2.6.18
是转移注意力并且无关紧要。
好消息是更新 libpthread_db
是 risk-free —— 如果你搞砸了,最坏的情况是 GDB 不能用于 multi-threaded 程序,但是因为这就是目前的状态,你不能让它变得更糟了。
但你应该可以做得更好:
- 下载 GLIBC-2.17 源代码,配置并构建它(但不要
make install
,否则您的系统可能会变砖)。 - 作为构建的一部分,现在应该存在
build/nptl_db/libthread_db.so.1
- 通过使用
set libthread-db-search-path /path/to/build/nptl_db
将 GDB 指向它并尝试再次调试您的程序来测试它。
如果可行,您可以用刚构建的 non-working /lib64/libthread_db.so.1
覆盖。
更新:
Is there any command I can use to grab some version information of these shared library files?
对于libpthread*.so.0
,这很简单:
gdb -q /lib/x86_64-linux-gnu/libpthread.so.0
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...
(gdb) x/s nptl_version
0x16037 <nptl_version>: "2.30"
对于 libthread_db.so.1
来说要困难得多:你需要反汇编 td_ta_new
,然后寻找 memcmp
调用,它可以被内联:
gdb -q /lib/x86_64-linux-gnu/libthread_db.so.1
Reading symbols from /lib/x86_64-linux-gnu/libthread_db.so.1...
(gdb) disas td_ta_new
Dump of assembler code for function td_ta_new:
0x0000000000002270 <+0>: push %r13
0x0000000000002272 <+2>: push %r12
0x0000000000002274 <+4>: push %rbp
0x0000000000002275 <+5>: mov %rsi,%rbp
...
0x00000000000022d6 <+102>: callq 0x2110 <ps_pdread@plt>
0x00000000000022db <+107>: mov %eax,%r12d
0x00000000000022de <+110>: test %eax,%eax
0x00000000000022e0 <+112>: jne 0x2318 <td_ta_new+168>
0x00000000000022e2 <+114>: cmpl [=11=]x30332e32,0x13(%rsp)
0x00000000000022ea <+122>: je 0x2340 <td_ta_new+208>
0x00000000000022ec <+124>: mov [=11=]x16,%r12d
0x00000000000022f2 <+130>: mov 0x18(%rsp),%rax
0x00000000000022f7 <+135>: xor %fs:0x28,%rax
0x0000000000002300 <+144>: jne 0x2388 <td_ta_new+280>
0x0000000000002306 <+150>: add [=11=]x28,%rsp
0x000000000000230a <+154>: mov %r12d,%eax
0x000000000000230d <+157>: pop %rbx
0x000000000000230e <+158>: pop %rbp
0x000000000000230f <+159>: pop %r12
0x0000000000002311 <+161>: pop %r13
0x0000000000002313 <+163>: retq
...
此处,地址 0x022e2
是对 memcmp("2.30", <data-read-from-nptl_version>, 5)
.