基本上,这是两个问题合而为一-因为如果我可以列出系统中导出的所有符号以及它们的共享库路径,那么我可以简单地grep
输出该内容。
对于内核符号,我想它会更容易-因为我们可以始终cat /proc/kallsyms
获取加载到内存中的那些模块的所有符号的列表;然后sudo cat /proc/modules
会提供已加载模块及其地址的列表,但不会给出模块从其加载的路径(如果它们是作为单独的树外.ko对象构建的)
例如,我尝试kst
使用ltrace
以下方法跟踪程序:
$ 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:查找定义了符号的库。; 我尝试过这样的事情:
$ 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
?)可能执行了一些这种符号查找,但是我尝试了各自的联机帮助页,并且在没有提供某种可执行文件作为命令的情况下,我看不到从命令行“查找”任何符号的方法。论点。附带问题-是否可以使用这些工具?
因此,我正在寻找一种命令行工具,其行为类似于(pseudocode):
$ ./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
外壳)看到的所有可用符号及其位置的列表。
Linux是否存在这样的工具?