Debugging

Malcolm Wallace Malcolm.Wallace@cs.york.ac.uk
Thu, 28 Aug 2003 16:07:39 +0100


Konrad Hinsen <hinsen@cnrs-orleans.fr> writes:

> > The Hat solution is to trace everything, and then use a specialised
> > query over the trace to narrow it to just the points you are interested
> 
> That sounds risky with programs that treat megabytes of data. It isn't
> always possible to test with small data sets, e.g. when different algorithms
> are used depending on the size of the problem.

Indeed, Hat can chew up disk space (to store the trace) at a
frightening rate.  The fastest I have witnessed so far is 50Mb per
second on one particularly intensive run, and we have certainly bumped
into a 2Gb single-file limit once or twice as well.  But backing
store is cheap, you can interrupt a computation early to use the
partial trace, and you can always 'trust' parts of the computation
to reduce the amount of storage needed.  However, you probably don't
know ahead of time where the fault is, so our philosophy is that it is
better to expensively store (once) everything that might turn out to
be relevant, and then cheaply browse it, than to go through several
cycles of edit/compile/expensive-run.

> >        like HOOD, it permits you to see the arguments and results of
> > a named function call,
> 
> I am mostly interested in intermediate values.

Intermediate values are always the result of an expression, and this
is exactly what hat-observe shows you - expressions and their results.

There is another trace-browser, hat-trail, used for tracing backwards
from an error or faulty output value to the expressions that produced
it.  This likewise shows all the intermediate values along the way.

> > Another idea is to permit real Haskell expressions to post-process the
> > result of the trace query, rather like meta-programming.  So your second
> 
> That sounds like a very flexible approach. Could one perhaps do this *while*
> the trace is being constructed, in a lazy evaluation fashion, such that 
> unwanted trace data is never generated and stored?

What an interesting idea.  Yes, I imagine that might be another good
avenue for us to explore.  Provided one could express the desired
trace query *before* running the program, at runtime the system would
need only to construct that part of the trace which is relevant to
the query.  This could improve the efficiency of tracing, but on the
other hand it severely limits the amount of information available at
the end.

Regards,
    Malcolm