how dynamic stack approximation works

Peter Hercek phercek at gmail.com
Sun Mar 1 09:09:53 EST 2009


Simon Marlow wrote:
> Peter Hercek wrote:
>> Sure, but the plan to maintain an approximate debugging dynamic stack 
>> depends on one thing:
>> The number of items (continuations) on the return stack  from the 
>> beginning of /case tick<n> of {_->e}/ to the moment when we can check 
>> the count of items in the return stack inside /tick<n>/ is constant 
>> and known for a given runtime version of ghc. Or variable but known 
>> for each call individually. This is important to find out the number 
>> of return addresses on the return stack just before the execution of 
>> /case tick<n> of {_->e}/.
> 
> I don't fully understand what it is you mean.  e.g. I don't know what 
> "from the beginning of /case tick<n> of {_->e}/" means.
> 
> Let me try to explain a couple of things that might (or might not!) help 
> clarify.  We don't normally see
> 
>  case tick<n> of { _ -> e }
> 
> because the byte-code generator turns this into
> 
>  let
>      z = case tick<n> of { _ -> e }
>  in
>      z
> 
> the debugger paper explains why we do this.  Anyway, the byte code for 
> the closure for z does this:
> 
>   - if the breakpoint at <n> is enabled then stop,
>   - otherwise, evaluate e
> 
> i.e. it doesn't push any stack frames.
> 
> Does that help frame your question?

I reread the paper and together with this it actually answered my question.

I thought that tick<n> represents a call to the debugger. But it is only 
a byte code which is checked by interpreter and if the debugging 
location is enabled then the interpreter breaks.

Also I have found out that what I originally intended would not work 
because the interpreter can beak only at the beginning of a BCO. But 
maybe there are other almost as good solutions. I'm aiming at these 
features:

* :next command with the meaning: Break at the next source span which 
has the same or smaller number of addresses on the return stack and 
which is not a subset of the current source span.

* :stepout command with the meaning: Break at the next source span which 
has smaller number of addresses on the return stack.

* build dynamic stack (more or less entirely in GHCi so if it is not 
used it should not slow down GHC code interpretation; well doing it in 
GHCi would mean it would be painfully slow because of thread switches 
but if it proves useful it can be moved to GHC)


* ... and maybe also something like the last one (or the last few) 
frames of lexical stack for the current source span; this one may not be 
even that interesting if options to filter trace log are fine enough; 
the problem with trace log is anything which is executed in a loop (so 
e.g. even some stupid lambda in a map cal)

I'm not aiming at full lexical stack. This is not a promise I'll 
implement the above things. I would like just some more information:

* what would be a good way (if any) to implement a new kind of break 
point: Break at any tick (source span) if number of addresses on the 
return stack is less than given number. Actually the ability to count 
number of return addresses (although useful) is not that important. It 
is important to find out whether the current return stack has more, 
less, or the same number of return adresses than it had in a given 
moment in past. Any good paper / web page where I could find how the 
return stack is actually implemented?

* any good paper / web page where I can find how GHC profiler derives 
lexical call stack approximation?

Thanks,
   Peter.






More information about the Glasgow-haskell-users mailing list