如何更新我的 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.16gdb使用libthread_db-1.0.so,[=22] =], 不匹配? (好吧,我不确定是否可以根据这些信息比较它们,我可以吗?)

是不是说现在我需要下载一个libthread_db-1.0.sofor GNU/Linux 2.6.16和link libthread_db.so.1我可以从哪里下载它

对了,我也觉得奇怪,我服务器上的libpthread-2.17.solibpthread-2.12.so2.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).

的内联调用