
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.