RFC: stack trace generation
Bryce McKinlay
mckinlay@redhat.com
Mon Jul 19 18:17:00 GMT 2004
Casey Marshall wrote:
>What I'm trying now is making the file/line number lookup code do so
>for the stack as a whole -- each `lookup' method in NameFinder would
>receive the entire stack trace and an array of objects to store the
>info it finds for each frame, skipping frames that have already been
>filled in. Then I call each in a precedence order -- interpreted,
>DWARF-2 info, dladdr, and finally (not implemented yet) addr2line.
>
>This makes the DWARF-2 part much faster, since it can optimize out of
>having to read things more than once. It also has room for inserting
>other methods for finding debug info; it isn't "pluggable", but it
>could be.
>
>
Perhaps the best thing to do would be to make Dwarf2NameFinder a class,
and have it remember whatever information/state about each .so is
necessary to speed up repeated lookups. This would work better than
passing an entire stack trace to the NameFinder, because different types
of NameFinder are required for different frames - eg interpreted frames,
and the logic to determine which name finder to use doesn't belong in
the NameFinder itself. I'd like to keep NameFinder's role simple.
What I do currently (not necessarily the best solution) is to
instantiate a NameFinder once for every Throwable.printStackTrace()
call. The NameFinder.lookup() method is then called once for each frame
with the IP for that frame. The namefinder determines which binary
contains the address, using dladdr(), and starts an addr2line instance
for that binary if necessary. The addr2line instances are kept open
until close() is called on the namefinder once the bottom of the stack
is reached. This means that the repeated lookup() calls do not each
cause a new addr2line instance to be started if there is one already
running for that binary.
Caching some data about each .so is presumably much less of a problem
than keeping around a huge (50MB+ !) addr2line instance, so we could
probably just keep the namefinder instance around for the lifetime of
the application, after the first printStackTrace() call? Perhaps we can
keep the mmap'ed .debug_line sections open too - presumably they can be
mapped read-only, so the overall effect on application memory usage
shouldn't be too significant?
>Bryce> I think reading the .debug_line info directly is definitely the
>Bryce> right solution. My only concern is this: + * DWARF-2 reading by
>Bryce> Casey Marshall <csm@gnu.org>. ELF info reading + * based on
>Bryce> elf/sprof.c from glibc-2.3.2, written by Ulrich Drepper + * and
>Bryce> Copyright (C) 1997-2002, 2003 Free Software Foundation, Inc.
>
>Bryce> Are we allowed to use this ELF code? Do we need to get special
>Bryce> permission from the FSF to use/relicense it?
>
>Maybe, that was one of my open questions about this. The code I used
>from glibc was very small -- basically a cluestick about how to mmap
>the ELF headers, and how to find and inspect section names.
>
>I could rewrite this part if need be, since I have a better grasp of
>ELF than when I started this.
>
>
I think this may be necessary, unfortunately.
Regards
Bryce
More information about the Java
mailing list