Resolving address -> symbol name in executables and shared libraries

Resolving address -> symbol name in executables and shared libraries

Post by r.. » Thu, 21 Nov 2002 00:39:18



Is it possible to take an address in a running program and
convert it to a symbol name? Or (better) a filename and line
number? I have access to the executable on disk and the shared
libraries, and they are compiled with debugging / not stripped.
The catch is that most of the 'interesting' addresses
will be in shared libraries which are opened with dlopen.

The running program needs to be able to display stats information
about itself - a kind of introspection.

Even a completely non-portable Linux-specific method would be
useful.

Rich.

--

http://www.annexia.org/

 
 
 

Resolving address -> symbol name in executables and shared libraries

Post by John Reise » Thu, 21 Nov 2002 02:02:43


  > Is it possible to take an address in a running program and
  > convert it to a symbol name? Or (better) a filename and line
  > number? ...
  >
  > The running program needs to be able to display stats information
  > about itself - a kind of introspection.

<dlfcn.h>:
-----
typedef struct
{
     __const char *dli_fname;      /* File name of defining object.  */
     void *dli_fbase;              /* Load address of that object.  */
     __const char *dli_sname;      /* Name of nearest symbol.  */
     void *dli_saddr;              /* Exact value of nearest symbol.  */

Quote:} Dl_info;

extern int dladdr (__const void *__address, Dl_info *__info) __THROW;
-----
Beware: dladdr is young.

For a subroutine call backtrace, see <execinfo.h>:
-----
extern int backtrace (void **__array, int __size) __THROW;
extern char **backtrace_symbols (void *__const *__array, int __size) __THROW;
extern void backtrace_symbols_fd (void *__const *__array, int __size, int __fd) __THROW;
-----
Beware: quality of implementation varies.

Sometimes you just have to do it by hand using <dlfcn.h>, <link.h>, <elf.h>:
        struct link_map const *const lm = dlopen(0, RTLD_LAZY);
then traverse the doubly-linked list of loaded modules.  Find the load address,
module, symbol table, debug info (on disk), and grovel.