Basically, this is two questions into one – because if I can list all symbols exported within a system, along with their shared library path, then I could simply grep
that output.
For kernel symbols, I guess it is somewhat easier – because we can always cat /proc/kallsyms
and get a list of all symbols of those modules loaded in memory; then sudo cat /proc/modules
will give a list of loaded modules with their addresses, but not the paths where does modules have been loaded from (if they are built as separate, out-of-tree .ko objects)
For instance, I try to trace the program kst
using 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
...
… and I would like to know where this _ZNK13QGraphicsItem10parentItemEv
resides.
So, what to do about shared library symbols? Reading through [gcc-help] Re: finding the library in which symbol is defined.; I tried something like this:
$ 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
...
… but that gives me additional problems: I don't really know all the paths which are scanned for shared libraries on my system, so when I first tried find /lib ...
it didn't find anything; I find this guessing of directories irksome, just as well as the alternative: scanning the entire root filesystem with find
… And also, I seem to hit up *.so's which cannot be opened by nm
(maybe because they are symlinks?), which output a quite a bit of error messages (which I don't like either).
The thing is – ldd
(or ld
?) probably performs some of this lookup of symbols, but I tried the respective manpages, and I cannot see a way to "find" any symbol from the command line, without providing some sort of executable file as an argument. Side question – would there a way to use these tools for that?
So, what I'm looking for a command line tool, which would behave something like (pseudocode):
$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...
… where I don't specify any directories to search – but which would also handle, e.g. LD_PRELOAD
or LD_LIBRARY_PATH
; say if I do:
$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'
… then I'd get the /path/to/mylib.so
where the given symbol was defined (given that such a symbol wouldn't exist in the standard libraries) – and would output "not found" otherwise. And otherwise, ./findsymbol --dumpall
could produce a list of all available symbols and their locations seen from a given environment (e.g. a specific bash
shell).
Does a tool like this exist for Linux?
Best Answer
The paths to look for libraries in will be listed in the file
/etc/ld.so.conf
, the environment variableLD_LIBRARY_PATH
and any RPATHs encoded into the ELF binary. The programldd
will tell you what libraries a specific application will load.Once you have a symbol you are curious about, you can use the program
nm
to dump symbols of.o
and.a
files andreadelf
to dump symbols from a.so
or any elf executable.Examples:
And finally, with that background aside, here is your holy grail:
Given a symbol
_ZN6Kopete6Global10PropertiesC2Ev
, where is this?which yields:
The
-l
flag says to search dirs in/etc/ld.so.conf
and the-s
specifies the symbol to find.