19

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?

13

The paths to look for libraries in will be listed in the file /etc/ld.so.conf, the environment variable LD_LIBRARY_PATH and any RPATHs encoded into the ELF binary. The program ldd 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 and readelf to dump symbols from a .so or any elf executable.

Examples:

nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so

And finally, with that background aside, here is your holy grail:

Given a symbol _ZN6Kopete6Global10PropertiesC2Ev, where is this?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

which yields:

ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4

The -l flag says to search dirs in /etc/ld.so.conf and the -s specifies the symbol to find.

  • This is incomplete: some programs load libraries from application-specific directories. – Gilles Dec 5 '13 at 1:08
  • 1
    @Gilles scanelf allows you to specify specific directories to search in and support recursive seaching with -r so you can tweak its search paths or search your entire system without too much trouble. For example scanelf -r -s SYMBOL /lib/* /usr/* /opt/* will find most of the places libraries are hiding. – casey Dec 5 '13 at 3:41
7

On GNU systems (when using the GNU libc dynamic linker), you can run your program as:

LD_DEBUG=bindings kst2

To find where the symbols resolve to.

0

I have run into this a number of times, trying to port code from one Linux system to another. Usually I just end up grep'ing all the standard directories. I couldn't find anything googling. So here is a quick script:

edt11x/findinsharedlibs

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.