Как мне обновить мою общую библиотеку libthread_db, чтобы она соответствовала общей библиотеке libpthread? - PullRequest
0 голосов
/ 07 августа 2020

Я использую 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 разделяемой библиотеки, которую я связываю, не соответствует версии libthread_db разделяемой библиотеки, которую gdb использует при отладке.

Я прочитал эти 2 связанных вопроса Невозможно отладить Многопотоковое приложение с предупреждениями об отладке gdb , GDB .

Затем я попытался выяснить, какая версия каждого из них, с помощью команды 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, несоответствие? (Ну, я не уверен, могу ли я сравнить их на основе этой информации, могу я ?)

Означает ли это, что теперь мне нужно загрузить libthread_db-1.0.so, который предназначен для for GNU/Linux 2.6.16 и ссылку libthread_db.so.1 на него? Где я могу его скачать из ?

Кстати, мне тоже странно, что для libpthread-2.17.so и libpthread-2.12.so на моем сервере 2.17 > 2.12 первый должен быть новее версия. Но это для младшей Linux версии (2.6.16), может кто просто скопирует и переименует файл? Я не знаю. : (

1 Ответ

1 голос
/ 10 августа 2020

Ваш вопрос является точной копией двух ответов, которые вы уже нашли: кто-то установил GLIB C -2.17 в вашу систему (в которой, вероятно, изначально был GLIB C -2.12), но не смог установить соответствие libthread_db.so.1.

Результат file - GNU/Linux 2.6.18 - отвлекающий маневр и не имеет значения.

Хорошая новость заключается в том, что обновление libpthread_db безрисково - если вы облажаться, худшее, что может случиться, это то, что GDB не будет работать для многопоточных программ, но, поскольку это текущее состояние, вы не можете сделать его хуже.

Но вы должны быть в состоянии сделать это лучше:

  • загрузите исходный код GLIB C -2.17, настройте и соберите его (но не make install, иначе вы, скорее всего, заблокируете свою систему).
  • как часть сборки, теперь должно существовать build/nptl_db/libthread_db.so.1
  • протестировать его, указав на него GDB с помощью set libthread-db-search-path /path/to/build/nptl_db и снова попытавшись отладить вашу программу.

Если это сработает , вы можете заменить нерабочий /lib64/libthread_db.so.1 только что созданным.

Updat e:

Есть ли какая-нибудь команда, которую я могу использовать для получения информации о версии этих файлов разделяемой библиотеки?

Для 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", <data-read-from-nptl_version>, 5).

...