How can I get more information about symbol by it's address in memory

2.8k views Asked by At

I'm trying to get the symbol name by its address in memory. I use int dladdr(void *addr, Dl_info *info) function from dlfcn.h to get the information:

typedef struct {
 const char *dli_fname;  /* Pathname of shared object that
                                          contains address */
 void       *dli_fbase;  /* Address at which shared object
                                          is loaded */
 const char *dli_sname;  /* Name of nearest symbol with address
                                          lower than addr */
 void       *dli_saddr;  /* Exact address of symbol named
                                          in dli_sname */
} Dl_info;

But this function can't find symbol matching the address and sets dli_sname and saddr to NULL.

How can I get the name of symbol or any other information (kind, attributes, etc.) about the symbol in this case?

NOTE: The name of the symbol I'm trying to find is _ZTv0_n24_N4QGst13PropertyProbeD0Ev. It's listed in the vtable of class QGst::PropertyProbe by g++ -fdump-class-hierarchy:

Vtable for QGst::PropertyProbe
QGst::PropertyProbe::_ZTVN4QGst13PropertyProbeE: 14u entries
...
80    (int (*)(...))QGst::PropertyProbe::_ZTv0_n24_N4QGst13PropertyProbeD1Ev
...

But it's not found by dladdr by its address that I've got when looking into the shared object by dlopen and dlsym of symbol _ZTVN4QGst13PropertyProbeE and iterating through the list of virtual function pointers. All other functions in the v-table are found by dladdr.

2

There are 2 answers

0
Employed Russian On BEST ANSWER

I'm trying to get the symbol name by it's address in memory.

What for?

I use int dladdr() ...

The first thing you need to understand is that dladdr only looks at dynamic symbol table of the ELF image, which often is much smaller than the static symbol table. You can see the contents of dynamic symbol table with nm -D.

For example, if you link a.out executable without -Wl,-E or -rdynamic flag, then main will not appear appear in the dynamic symbol table, and thus will be "invisible" to dladdr.

The second thing you need to know is that when you link a shared library, you can control exactly what symbols do and do not get exported from it (exported symbols are the ones that have dynamic symbol table entries). There are various methods for doing this: linker version scripts, -fvisibility flags, attribute((visibility(...))).

All this is to say that finding a symbol that dladdr can't tell you anything about should not at all be surprising.

1
Blake On

Try objdump --syms. That should print the (mangled) symbol names and their addresses. See http://linux.die.net/man/1/objdump.