From: sinbad on
hi,

how to use the addr2line utility on a daemon which gets linked with a
dynamic library.
my actual address point lies in the dynamic library. i tried using
addr2line both on
the daemon and dynamic library, it threw me junk. since, the daemon
gets linked dynamically,
i am sure using addr2line on daemon or dynamic library on the
filesystem doesn't make
sense. I am not sure how to go about this. any pointers will be
helpful. btw, my target is
powerpc-linux.

thanks
sinbad
From: Xavier Roche on
sinbad wrote:
> how to use the addr2line utility on a daemon which gets linked with a
> dynamic library.

This might help you or not, but in my memories, the addr2line tool
wanted me to give the address relative to the base address for code not
in the "main program" ; ie. for a function pointer of a library X, the
address would be ( address - dladdr(ptr).dli_saddr ) [pseudo-code]
From: Xavier Roche on
sinbad wrote:
> how to use the addr2line utility on a daemon which gets linked with a
> dynamic library.

This might help you or not, but in my memories, the addr2line tool
wanted me to give the address relative to the base address for code not
in the "main program" ; ie. for a function pointer of a library X, the
address would be ( address - dladdr(ptr).dli_saddr ) [pseudo-code]

Of course, with a different addr2line per module (.so/..), with the
relative address.

There might be another way, but this one appeared to work.
From: Jens Thoms Toerring on
sinbad <sinbad.sinbad(a)gmail.com> wrote:
> how to use the addr2line utility on a daemon which gets linked with a
> dynamic library.
> my actual address point lies in the dynamic library. i tried using
> addr2line both on
> the daemon and dynamic library, it threw me junk. since, the daemon
> gets linked dynamically,
> i am sure using addr2line on daemon or dynamic library on the
> filesystem doesn't make
> sense. I am not sure how to go about this. any pointers will be
> helpful. btw, my target is
> powerpc-linux.

Starting question: where did you get the address from? Since I
don't know I assume that you got it from a call of backtrace().
In that case you can use the address directly if it's within
the program but not when it's in a dynamically linked library.
As Xavier pointed out you first have to subtract from this
address the offset from where the libraryt is linked into
the program. And to find out that offset you can use the
dladdr() function, passing it the address under considera-
tion (but note that this is a Glibc extension and thus not
available on all POSIX compliant systems). See the man page
for dlopen() for the complete description of dladdr(). The
dladdr() function fills in a structure of type 'Dl_info' and
it contails a member 'dli_fbase' which is just the offset you
need to subtract from the address before you can pass it to
addr2line. Of course you then have to apply addr2line to the
shared library together with the offset-corrected address to
get anything reasonable out of it, to find out what the path
of the shared library is use the 'dli_fname' member of the
structure returned by dladdr().

Here's a bit of untested code (but similar to what I am using
in a program that prints out a readable backtrace when it
crashes):

void invoke_addr2line_on_so( void * address )
{
Dl_info info;
char buf[ 1024 ];

dladdr( address, &info );
sprintf( buf, "addr2line -e %s %p\n", info.dli_fname,
( void * ) ( ( char * ) address )
- ( char * ) info.dli_fbase ) );
system( buf );
}

If your program is a daemon or not shouldn't make any
difference except that a daemon doesn't have a standard
output, so instead of using system() you will have to find
some other other means to catch the output of addr2line
and make it visible. You could e.g. write out the off-
set-corrected address and the name of the shared library
to a log file instead and then run addr2line manually
using this information.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt(a)toerring.de
\__________________________ http://toerring.de