【问题标题】:How do I update my libthread_db shared library so as to match libpthread shared library?如何更新我的 libthread_db 共享库以匹配 libpthread 共享库?
【发布时间】:2020-08-07 08:25:39
【问题描述】:

我正在使用 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.

然后我意识到问题是我链接的libpthread共享库的版本与gdb在调试时使用的libthread_db共享库的版本不匹配。

我阅读了这两个相关问题Unable to Debug Multi-Threaded Application with gdbGDB 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

所以我的程序链接到libpthread-2.17.so ,用于for GNU/Linux 2.6.16,而gdb 使用libthread_db-1.0.so,用于for GNU/Linux 2.6.18,不匹配? (好吧,我不确定是否可以根据这些信息比较它们,我可以吗?)

这是否意味着现在我需要下载一个用于for GNU/Linux 2.6.16libthread_db-1.0.so 并将libthread_db.so.1 链接到它? 我可以从哪里下载它

顺便说一句,我也觉得奇怪,对于我服务器上的libpthread-2.17.solibpthread-2.12.so2.17 > 2.12,前者应该是更新的版本。但它适用于较低的 Linux 版本(2.6.16),也许有人只是复制它并重命名文件?我不知道。 :(

【问题讨论】:

  • 不幸的是,在 CentOS 中更新库是一个皮塔,可能会导致系统变砖。你可以做的是下载 thread_db 的源代码(或其他任何名称)并自己编译它。然后安装它别处。然后将新的库路径添加到 LD_LIBRARY_PATH
  • @ewong 我不能只下载一个用于for GNU/Linux 2.6.16libthread_db.so.1,然后创建一个符号链接libthread_db.so.1 -> the one I download.so 吗?
  • 假设它适合您的系统,我相信如此。我只是通常构建它并在其他地方安装库.. 抱歉无法提供帮助
  • @Rick 这个blog post 可能会有所帮助

标签: linux gdb shared-libraries


【解决方案1】:

您的问题与您已经找到的两个答案完全相同:有人在您的系统上安装了 GLIBC-2.17(最初可能安装了 GLIBC-2.12),但未能安装匹配的 libthread_db.so.1

file 的输出 -- GNU/Linux 2.6.18 是红鲱鱼,无关紧要。

好消息是更新libpthread_db 是没有风险的——如果你搞砸了,可能发生的最坏情况是 GDB 不能用于多线程程序,但由于这是当前状态,你可以不要让它变得更糟。

但你应该可以做得更好:

  • 下载 GLIBC-2.17 源代码,配置并构建它(但不要make install,否则你可能会破坏你的系统)。
  • 作为构建的一部分,现在应该存在build/nptl_db/libthread_db.so.1
  • 通过使用 set libthread-db-search-path /path/to/build/nptl_db 将 GDB 指向它并尝试再次调试您的程序来测试它。

如果可行,您可以用刚刚构建的/lib64/libthread_db.so.1 覆盖不工作的/lib64/libthread_db.so.1

更新:

有什么命令可以用来获取这些共享库文件的一些版本信息吗?

对于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   $0x30332e32,0x13(%rsp)
   0x00000000000022ea <+122>:   je     0x2340 <td_ta_new+208>
   0x00000000000022ec <+124>:   mov    $0x16,%r12d
   0x00000000000022f2 <+130>:   mov    0x18(%rsp),%rax
   0x00000000000022f7 <+135>:   xor    %fs:0x28,%rax
   0x0000000000002300 <+144>:   jne    0x2388 <td_ta_new+280>
   0x0000000000002306 <+150>:   add    $0x28,%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", &lt;data-read-from-nptl_version&gt;, 5) 的内联调用。

【讨论】:

  • 非常感谢。我稍后会尝试您的解决方案并接受您的回答。顺便说一句,既然file的输出无关紧要,那我怎么知道libthread_db.so.1的版本和libpthread-2.17.so的版本呢?有什么命令可以用来获取这些共享库文件的一些版本信息吗?因为有人可以将共享库文件重命名为他们喜欢的任何版本。
  • @Rick 不幸的是,没有简单的方法可以推断出 libthread_db.so.1 对应的 GLIBC 版本。
  • pthread 共享库libpthread-x.x.so 都不是?
猜你喜欢
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
  • 2020-10-06
  • 2015-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多