"goto_caller( 2 )" returns to caller( 2 )'s context

jjore on 2008-01-18T02:20:22

Work has sponsored a week of hacking and I've spent it doing stack tricks. I hope to use these features to build a better debugger. For now, here's the latest function. Consider what caller( N ) does. Now consider a goto( N ) that pops the stack back up N frames.

I plan to use it to let a debugger pop up to any level in the currently running program and resume from anywhere reasonable.


wild

dagolden on 2008-01-18T03:09:57

That sounds wild and cool -- but please give some thought along the way to how it will play with things that already fiddle with caller (e.g. Sub::Uplevel, Hook::LexWrap, Contextual::Return)

-- dagolden

Re:wild

jjore on 2008-01-18T04:02:55

I dunno, in an ideal world Sub::Uplevel wouldn't exist. I'm not sure there's a part of the stack that shouldn't be visible at all times including control structures like loops.

Right now caller() doesn't show loops but it *could*.

Re:wild

nothingmuch on 2008-01-18T12:20:53

Conversely I think high level stack delimitation could be useful...

It would be nice to have a wrapper for a low level caller() that returns every single scope, and then filters it, for example to skip things marked as wrappers, or to cut off any calls within local to a certain class or Carp clan or some explicit delimiter. Code that uses caller() is generally either tricky code that wants as much detail as possible, or code that is being tricked and really cares only about high level things.

Maybe there's yet another Devel module in it =)

Implementation?

educated_foo on 2008-01-18T15:19:45

Would you mind talking a bit about the implementation? I looked into doing something like this for Sepia's debugger, and didn't come up with anything satisfactory. I tried defining a DB::sub with a label in it and using "goto LABEL" to jump out of any number of levels of call, but this dramatically slows down the program. The other approach I thought of was to copy the machinery used by eval/die (setting PL_restartop, etc.) in an xsub, but I haven't found the tuits to finish this yet.