linux – 查找在实时系统上定义的共享库符号的位置/列出系统上导出的所有符号
作者:互联网
基本上,这是两个问题合二为一 – 因为如果我可以列出系统中导出的所有符号以及它们的共享库路径,那么我可以简单地grep该输出.
对于内核符号,我想它有点容易 – 因为我们总是可以cat / proc / kallsyms并获得内存中加载的那些模块的所有符号的列表;那么sudo cat / proc / modules将给出一个已加载模块及其地址的列表,但不会给出加载模块的路径(如果它们是作为单独的树外.ko对象构建的)
例如,我尝试使用ltrace跟踪程序kst:
$ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800
...
…我想知道_ZNK13QGraphicsItem10parentItemEv所在的位置.
那么,如何处理共享库符号呢?阅读[gcc-help] Re: finding the library in which symbol is defined.;我试过这样的事情:
$find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...
…但是这给了我额外的问题:我真的不知道在我的系统上扫描共享库的所有路径,所以当我第一次尝试使用find / lib时…它没有找到任何东西;我发现这个目录的猜测令人厌烦,就像另一种选择:用find扫描整个根文件系统……而且,我似乎遇到了* .so无法用nm打开(也许是因为它们是符号链接?) ,它输出了相当多的错误信息(我也不喜欢).
事情是 – ldd(或ld?)可能会执行一些符号查找,但我尝试了各自的联机帮助页,我看不到从命令行“查找”任何符号的方法,而没有提供某种可执行文件作为一个论点.附带问题 – 有没有办法使用这些工具呢?
那么,我正在寻找一个命令行工具,它的行为类似于(伪代码):
$./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...
…我没有指定任何要搜索的目录 – 但是也可以处理,例如LD_PRELOAD或LD_LIBRARY_PATH;如果我这样说:
$LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'
…然后我得到/path/to/mylib.so,其中定义了给定的符号(假设标准库中不存在这样的符号) – 否则将输出“未找到”.否则,./ findsymbol –dumpall可以生成从给定环境(例如特定的bash shell)看到的所有可用符号及其位置的列表.
这样的工具是否适用于Linux?
解决方法:
查找库的路径将列在文件/etc/ld.so.conf,环境变量LD_LIBRARY_PATH和编码到ELF二进制文件中的任何RPATH中.程序ldd将告诉您特定应用程序将加载哪些库.
一旦你有一个你很好奇的符号,就可以使用程序nm来转储.o和.a文件的符号,并使用readelf转储来自.so或任何elf可执行文件的符号.
例子:
nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so
最后,抛开那个背景,这是你的圣杯:
给定一个符号_ZN6Kopete6Global10PropertiesC2Ev,这是什么?
scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev
产量:
ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4
-l标志表示在/etc/ld.so.conf中搜索dirs,-s指定要查找的符号.
标签:dynamic-linking,linux 来源: https://codeday.me/bug/20190808/1625476.html