Enable stack traces with ghci -fexternal-interpreter -prof
ClosedPublic

Authored by simonmar on Jan 7 2016, 10:09 AM.

Details

Summary

The main goal here is enable stack traces in GHCi. After this change,
if you start GHCi like this:

ghci -fexternal-interpreter -prof

(which requires packages to be built for profiling, but not GHC
itself) then the interpreter manages cost-centre stacks during
execution and can produce a stack trace on request. Call locations
are available for all interpreted code, and any compiled code that was
built with the -fprof-auto familiy of flags.

There are a couple of ways to get a stack trace:

  • error/undefined automatically get one attached
  • Debug.Trace.traceStack can be used anywhere, and prints the current stack

Because the interpreter is running in a separate process, only the
interpreted code is running in profiled mode and the compiler itself
isn't slowed down by profiling.

The GHCi debugger still doesn't work with -fexternal-interpreter,
although this patch gets it a step closer. Most of the functionality
of breakpoints is implemented, but the runtime value introspection is
still not supported.

Along the way I also did some refactoring and added type arguments to
the various remote pointer types in GHCi.RemotePtr, so there's
better type safety and documentation in the bridge code between GHC
and ghc-iserv.

Test Plan

validate

Diff Detail

Repository
rGHC Glasgow Haskell Compiler
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
simonmar retitled this revision from to Enable stack traces with ghci -fexternal-interpreter -prof.Jan 7 2016, 10:09 AM
simonmar updated this object.
simonmar edited the test plan for this revision. (Show Details)
simonmar added reviewers: bgamari, ezyang.
simonmar updated the Trac tickets for this revision.
ezyang added a comment.Jan 7 2016, 2:25 PM

Very out of my depth in my patch, but it looks reasonable. The refactoring does make it a bit harder to read; where are the primary changes that enable stack traces with remote GHCi? I noticed that some of the C-- dispatch code has changed.

compiler/deSugar/Coverage.hs
71

What's the difference between Just emptyModBreaks and Nothing?

164–167

Took me a moment to realize this was "null terminate"

@ezyang - thanks for taking a look! No need for a full review, I just thought you might be interested.

where are the primary changes that enable stack traces with remote GHCi?

The BRK_FUN instruction in the interpreter pushes a cost centre on the stack, but before this patch BRK_FUN didn't work with the external interpreter because it had some same-heap assumptions, so breakpoints were disabled with -fexternal-interpreter. This patch removes all the same-heap assumptions for BRK_FUN, so that we can enable them in the external interpreter and thereby get stack traces.

compiler/deSugar/Coverage.hs
71

I wanted to get rid of emptyModBreaks because to make it work means creating an empty BreakArray on the server, which means passing in HscEnv and putting it in the IO monad (currently emptyModBreaks uses _|_ for the BreakArray, which is wrong). So I didn't completely manage to get rid of it, but it's gone in all the important places. Maybe is much better.

This revision was automatically updated to reflect the committed changes.