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
.
What for?
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 withnm -D
.For example, if you link
a.out
executable without-Wl,-E
or-rdynamic
flag, thenmain
will not appear appear in the dynamic symbol table, and thus will be "invisible" todladdr
.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.