failure implementing :next command in ghci
Peter Hercek
phercek at gmail.com
Sun Apr 12 13:26:23 EDT 2009
Hi,
So I wanted to give implementing :next ghci debugger command a shot. It
looked easy and I could use it. Moreover it would give me an easy way to
implement dynamic stack in ghci (using similar approach as used for
trace) ... well if I would feel like that since I was a bit discouraged
about it. The problem is I failed miserably. I still think it is easy to
do. I just do not know how to create correct arguments for
rts_breakpoint_io_action and I have given up finding up myself for now.
The proposed meaning for :next
Lets mark dynamic stack size at a breakpoint (at which we issue :next)
as breakStackSize and its selected expression as breakSpan. Then :next
would single step till any of these is true:
1) current dynamic stack size is smaller than breakStackSize
2) current dynamic stack size is equal to breakStackSize and the current
selected expression is not a subset of breakSpan
I hope the above would make good sense but I do not really know since
maybe rts does some funny things with stack sometimes. If you think the
proposed behavior is garbage let me know why so that I do not waste more
time with this :)
Ok, lets get back to why I failed. I think anybody who knows rts well
could probably tell me what's wrong in few minutes. The patch
representing my attempt is attached. It is done against the latest ghc
(head branch). I want to add stack size as the last argument of
rts_breakpoint_io_action so its signature would change from:
Bool -> BreakInfo -> HValue -> IO ()
to:
Bool -> BreakInfo -> HValue -> Int -> IO ()
Since dynamic stack is continuous I can find out stack size easily. I
did not implemented this yet, as well I did not implement this at all
for exceptions. The only thing I cared for now is passing one more
integer to rts_breakpoint_io_action. The argument contains only zero now
but that should be enough to see if I can add one more argument.
I tested it by loading this source code to ghci:
f :: Int -> Int
f x = x + 1
a = f 1
... then I used ":break f" and ":force a" in ghci to see whether I can
pass the new argument correctly. This test works since I added printing
of the last argument (the wanna be stack size) in
noBreakAction :: Bool -> BreakInfo -> HValue -> Int -> IO ()
noBreakAction False _ _ x = putStrLn $ "*** Ignoring breakpoint " ++ show x
noBreakAction True _ _ _ = return () -- exception: just continue
The noBreakAction implementation is just a test for now. Unfortunately
when I force the last argument it crashes. I think it is because I do
not create the closure for it correctly in the code for bci_BRK_FUN in
rts/Interpreter.c. Can somebody tell me what is wrong there or where to
find more information about how to fill in the stack with
rts_breakpoint_io_action arguments correctly?
Also, any information somewhere about where to use allocate and where to
use allocateLocal? I was surprised a bit that interpretBCO uses allocate
much but no allocateLocal which is supposed to be quicker for a single
thread.
I skimmed all of ghc commentary and read the pages which looked related
carefully but either it is not there or I missed it :-(
Thanks,
Peter.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: stackSize.patch
Type: text/x-patch
Size: 6642 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/glasgow-haskell-users/attachments/20090412/24dbf35c/stackSize.bin
More information about the Glasgow-haskell-users
mailing list