Using dwfl to enumerate frames of current thread

Ben Gamari ben at smart-cactus.org
Thu Aug 20 11:09:50 UTC 2015


Ben Gamari <ben at smart-cactus.org> writes:

> Mark Wielaard <mjw at redhat.com> writes:
>
>> On Wed, 2015-08-19 at 14:11 +0200, Ben Gamari wrote:
>>> I am adding full DWARF unwinding-based backtrace support to the Glasgow
>>> Haskell Compiler's (GHC) runtime system. GHC now emits DWARF information
>>> in the object files it produces [1] and we would like to be able to
>>> record full backtraces on both runtime system events and the user's
>>> request.
>>
>> Nice. The [1] doesn't point anywhere though.
>>
> Doh.
>
> This was supposed to point to Peter Wortmann's thesis [1]. As you might
> imagine, generating useful line number information for a
> lazily evaluated language without compromising optimization
> opportunities is not a trivial task. Peter deserves quite some credit
> for getting this working.
>
>>> The goal here is to expose a function to the runtime system and user
>>> programs allowing them to get a snapshot of the calling thread's current
>>> call-stack.
>>
>> I don't want to push you away from using elfutils, but have you looked
>> at gcc's libbacktrace? That seems to be made precisely for your use case
>> (it is how gccgo provides call-stacks to the go runtime).
>> https://gcc.gnu.org/git/?p=gcc.git;a=tree;f=libbacktrace;hb=HEAD
>>
> This looks great although it's not immediately clear to me whether/how
> it handles symbols from shared objects (which unfortunately GHC now
> produces and links against by default).
>
It turns out that libbacktrace only uses DWARF line information, not
the .debug_frames unwinding information. This means that we would have
needed to implement our own unwinder for the Haskell stack (separate
From the C stack). Unfortunately libbacktrace doesn't provide the
necessary tools to make this feasible. I also ended up looking at
libunwind, which seems to have similar goals to libbacktrace and also
suffers from the same insufficient interfaces.

So, I've come back to libdw. At this point I have basic stacktrace
output for the C stack using libdw's unwinder. My set_initial_registers
implementation can be found here [1]. It seems to work reasonably well
although I would appreciate a second pair of eyes to ensure I didn't
miss something.

Moreover, I have also implemented unwinding of the Haskell evaluation
stack (the stack used by Haskell code). While the unwinding and symbol
lookup work, I'm not getting any line information out of libdw. I'm
quite certain that my object (namely a statically linked executable) has
proper line information as addr2line can extract meaningful positions
for the addresses found in my stacktraces.

My stacktrace implementation is quite simple [2] and I suspect I'm
merely missing something obvious. Can anyone spot what I've missed?

Thanks,

- Ben


[1] https://github.com/ghc/ghc/compare/142a673...bgamari:libdw#diff-c6aeaf799bec63621050f2515ca3ba9eR207
[2] https://github.com/ghc/ghc/compare/142a673...bgamari:libdw#diff-c6aeaf799bec63621050f2515ca3ba9eR241

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 472 bytes
Desc: not available
URL: <https://lists.fedorahosted.org/pipermail/elfutils-devel/attachments/20150820/cdedc949/attachment.sig>


More information about the elfutils-devel mailing list