I have a Solaris process, which is a C++ application that is loaded by ld with a few .so libraries. This application has a function that gets a return address in the calling function and then tries to determine the name of the said calling function.
If I use dladdr(3) for that, it does not always put what I expect to see in Dl_info::dli_sname. It looks like it returns a name of a function that is not nearest below or at the pointer value. If I take the pointer value and look at the output of nm, I can match the value to the exact function I expect it to be.
I am wondering if there is a way to retrieve a symbol map for a process and let it search for the function name without using dladdr(3). I am especially interested to get a symbol map not just for the executable itself but also for all .so libraries that it has loaded.
I’m running on Solaris10/SPARC and I’m using gcc 4.2.x.
Thank you!
I have tried a simple test using
dladdr()on Solaris 10/SPARC (but caveats: GCC 3.4, straight C), and this works fine for me:Output:
This also works correctly if I write (for example)
You say you can resolve correctly against the output of
nmso possibilities seem limited… are you certain that the return address is being derived or passed correctly to your resolver function? I guess you are using the GCC builtins for this? I have tested__builtin_return_address(0)and this also works fine for me. If you are using the GCC builtins, did you call__builtin_extract_return_address()(see above page for details, mentions SPARC explicitly)? Can you post your code?Can you stretch slightly to “process re-reading it’s own binary/shared object files”? If so then libelf may be a way forwards. This is exactly what some of those utilities you mention are using, eg
nm: http://cr.opensolaris.org/~devnull/6515400/usr/src/cmd/sgs/nm/common/nm.c.htmlThis introductory article from sun.com might be of use (warning: article is 10 years old).
This isn’t as nice as doing native introspection and it’s odd that
dladdr(3C)doesn’t work 🙁Alternative intermediate: have you tried the
RTLD_DL_SYMENTflag todladdr1(3C)(and then perhaps borrow fromnm.cas above on the returned ELF sym)?