Как узнать, в какой библиотеке определена определенная функция?
[[email protected] memcached-1.4.5]# objdump -R memcached-debug |grep freeaddrinfo
0000000000629e10 R_X86_64_JUMP_SLOT freeaddrinfo
...
(gdb) disas freeaddrinfo
Dump of assembler code for function freeaddrinfo:
0x00000037aa4baf10 <freeaddrinfo+0>: push %rbp
0x00000037aa4baf11 <freeaddrinfo+1>: push %rbx
0x00000037aa4baf12 <freeaddrinfo+2>: mov %rdi,%rbx
Итак, я знаю, что freeaddrinfo
- динамически связанная функция, но как узнать, какой .so
он определил в?
Ответы
Ответ 1
См. этот ответ. info symbol freeadrinfo
- это один из способов узнать.
В Linux и Solaris вы также можете использовать ldd
и LD_DEBUG=symbols
. Например, если вы хотите узнать, откуда localtime
в /bin/date
:
LD_DEBUG=bindings ldd -r /bin/date 2>&1 | grep localtime
26322: binding file /bin/date [0] to /lib/libc.so.6 [0]: normal symbol `localtime' [GLIBC_2.2.5]
Ответ 2
Для определенной версии gdb с низкой версией "информационный символ" не может работать так, как вы хотите.
Поэтому, пожалуйста, используйте метод ниже:
-
Запустите 'p symbol_name', чтобы получить адрес символа
(gdb) p test_fun
$1 = {<text variable, no debug info>} 0x84bcc4 <test_fun>
-
Проверить/proc/ PID/карты, чтобы узнать, в каком модуле находится адрес символа.
# more /proc/23275/maps
007ce000-0085f000 r-xp 00000000 fd:00 3524598 /usr/lib/libtest.so
0x84bcc4 находится в [007ce000, 0085f000]
Ответ 3
Внутри каталога библиотек вы можете выполнить следующую команду для поиска определенного символа во всех библиотеках:
for file in $(ls -1 *.so); do echo "-------> $file"; nm $file; done | c++filt | grep SYMBOL*
Усовершенствованная версия будет состоять в том, чтобы перечислить все библиотеки, которые связаны с исполняемым файлом (через ldd), и перейти после поиска каждой библиотеки, если там определен символ. В зависимости от вашего * nix вам может потребоваться настроить разбор разреза:
APP=firefox; for symbol in $(nm -D $APP | grep "U " | cut -b12-); do for library in $(ldd $APP | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;