could ghci debugger search for free variables better?
Peter Hercek
phercek at gmail.com
Fri Oct 24 18:50:28 EDT 2008
Simon Marlow wrote:
> We thought about this when working on the debugger, and the problem is
> that to make the debugger retain all the variables that are in scope
> rather than just free in the expression adds a lot of overhead, and it
> fundamentally changes the structure of the generated code: everything
> becomes recursive, for one thing. Well, perhaps you could omit all the
> recursive references (except the ones that are also free?), but there
> would still be a lot of overhead due to having to retain all those extra
> references.
>
> It also risks creating serious space leaks, by retaining references to
> things that the program would normally discard.
>
> Fortunately it's usually easy to work around the limitation, just by
> adding extra references to your code, e.g. in a let expression that
> isn't used.
Yes, Pepe pointed this to me too along with the "Step inside
GHCi debugger" paper in monad reader. The problem is that
I mostly can find out what is wrong when I look at values of
some important variables when some important place in my code
is hit. Using the trick with const function to manually add
references is not that much better than simple "printf
debugging" (adding Debug.Trace.trace calls to the code).
Tracing the execution history is nice too but it provides
much more than what is needed and obscures the important parts.
OK, It is frustrating that I find "printf debugging" often more
productive than ghci debugger.
I see that it is not a good idea to keep references to all the
variables in scope but maybe few improvements are possible:
1) As there is :steplocal, there should be also :tracelocal.
It would keep history of evaluations within given function
then when user asks for a variable it would be searched
first in the selected expression and if not found in the
expressions from the tracelocal history. If the result
would be printed from tracelocal history it should be indicated
so in the output. This would avoid the tedious task of
searching the trace history manually and moreover it would
limit the history to the interesting parts (so hopefully
the depth of 50 would be enough). The results from the
tracelocal history may not be from the expected scope
sometimes but the same problem is with "printf debugging".
2) I noticed only now that I do not know how to script
breakpoints. I tried
:set stop if myFreeVar == 666 then :list else :continue
... and it did not work. My goal was to create a conditional
breakpoint. I also wanted to use it instead of "printf
debugging" using something like
:set stop { :force myFreeVar; :continue }
Ideally it should be possible to attach
different script for each breakpoint and the functions
for controlling debugger should be available in the
Haskell. I would expect this is already partially possible
now (using :set stop) and possibly some functions from
ghci api which correspond to ghci commands (like :set etc.).
But I do not know how, any pointers from experienced ghci
debugger users?
Ghci debugger did not know some functions in my code which
I would expect it to know; e.g. field selection functions
from a record which is not exported from the module but
which are available withing module. Is this expected?
(I did not have any *.hi *.o files around when ghci did run
the code.)
Och and sometimes it did not recognize a free variable in
the selected expression. The code looked like
let myFn x = x `div` getDivisor state > 100 in
if myFn xxx then ...
the expression "myFn xxx" was selected while browsing trace
history but xxx was not recognized, but when I browsed into
myFn definition in the trace log the x (which represented
the same value) was recognized. Is this expected?
Thanks,
Peter.
More information about the Glasgow-haskell-users
mailing list