如何知道特定函数定义在哪个库中?

10
[root@xxx 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文件中定义的?


2
你需要认真审查你的问题并接受一些答案。 - karlphillip
3个回答

8
请参考这个答案。其中,info symbol freeadrinfo是一种查找的方法。
在Linux和Solaris上,你也可以使用lddLD_DEBUG=symbols。例如,如果你想知道/bin/date中的localtime来自哪里:
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]

太棒了。非常感谢你! - Mihai Todor

2

对于某些低版本的gdb,“info symbol”可能无法按照您想要的方式工作。

因此,请使用以下方法:

  1. 运行“p symbol_name”以获取符号地址

    (gdb) p test_fun $1 = {<text variable, no debug info>} 0x84bcc4 <test_fun>

  2. 检查/proc/PID/maps,找出符号地址所在的模块。

    # more /proc/23275/maps 007ce000-0085f000 r-xp 00000000 fd:00 3524598 /usr/lib/libtest.so

    0x84bcc4在[007ce000, 0085f000]中


0

在libraries目录中,您可以执行以下命令来搜索所有库中的特定符号:

for file in $(ls -1 *.so); do echo "-------> $file"; nm $file; done | c++filt | grep SYMBOL*

升级版将列出与可执行文件链接的所有库(通过ldd),并在每个列出的库中搜索是否定义了该符号。根据您的*nix,您可能需要调整cut解析:

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;

1
如果您使用'nm -A',则第一个版本可以大大减少。 '$(ls -1 .so)'是完全错误的--' .so'同样有效。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接