Debugging with GHCi.
simonmarhaskell at gmail.com
Mon Apr 3 15:39:51 EDT 2006
> On 4/3/06, Simon Marlow <simonmarhaskell at gmail.com> wrote:
>>case, my plan was to implement a generic object viewer, using the
>>information that GHCi already knows about datatypes - if you can map
>>info tables to DataCons, then it is possible to display any constructors
>>in the heap. Some support from the Linker is required. Displaying a
>>thunk wouldn't evaluate the thunk, it would just print something like
>>'_x37', or maybe a more detailed representation of the thunk such as the
>>source location of the expression it represents.
> Is it possible to display such detailed representations without
> compiling the standard libraries in debug mode?
Yes, absolutely. That's the great thing about being in GHCi, we have
all the compiler's information about the code to hand - including full
definitions of data types. So for a given constructor application in
the heap, we can print a source-code representation of it, even
compensating for the fact that the runtime representation of a
constructor may be different from the source code representation
(unboxed fields, existential dictionaries, etc.).
>>I also wanted to make it possible to insert breakpoints dynamically,
>>i.e. without recompiling the code. It would involve overwriting a BCO
>>in the heap with a special breakpoint object. BCOs will also need
>>information about the names of free variables and a source location. In
>>general, the compiler will need to track source locations through the
>>middle end more than it currently does.
> This sounds really difficult. Are you sure it won't result in a low
> power/complexity ratio? I mean, is it really that much of a problem to
> recompile the code?
Quite right, it's difficult. Your idea has a much better
power-to-weight ratio. We must have it! It's a great basis for adding
further debugging support, I hope you plan to commit it.
Some other random ideas: The breakpoint should print out the source
location ("stopped at Foo.hs:26:13..."). GHCi could keep track of all
the breakpoints in the program, enable you to turn them on or off
individually, ignore them for a specified number of times. We could
provide conditional breakpoints, too. Assertions (Prelude.assert)
should trigger a break if they fail, as should other kinds of exception.
Another part of our vague debugging plan was to add a cheap form of
cost-centre stacks to the byte code interpreter, so that you could
always get a backtrace at a breakpoint or an exception. We don't know
what this "cheap form of CCS" would look like, though.
>>The ultimate goal is that you could click on a source line in hIDE to
>>set a breakopint, run the program, and display the contents of local
>>variables when the breakpoint is hit.
> I agree on the overall goal. However, I don't like the idea of
> line-based checkpoints, and the entry point of a program (if it even
> exists) should receive no special attention over any other function.
Ok, ok. Breaking at a given line doesn't usually make a great deal of
sense in Haskell. Instead, it would mean clicking on certain syntactic
elements - function and variable definitions, and perhaps smaller
expression-level elements such as an if-expression. There's enough
information in the abstract syntax to figure out which expression you
clicked on, and even to highlight it as you hover the mouse around.
When I say "run the program", of course I really mean "type an
expression at the GHCi prompt".
More information about the Cvs-ghc