Re: PadWalker, eval and perl5db

2011-11-23 Thread Rocky Bernstein
On Wed, Nov 23, 2011 at 8:06 AM, Brock  wrote:

> On Sun, 20 Nov 2011 Rocky Bernstein wrote:
> > I've briefly looked at PadWalker which can look at "my" and "our"
> > variables on a call stack. And while this is very useful, it is not
> > the same as being able to evaluate a string in the context of a stack
> > frame.
> >
> > Has anyone tried to create such an eval? A simple suggested interface
> > would be to pass it an integer which indicates the call stack frame to
> > use.
>
> You might take a look at Eval::WithLexicals and how it is used in
> Plack::Middleware::InteractiveDebugger (which, upon die(), lets the user
> open a web-based REPL at any level of the call stack). Looks like there
> is some manual work you have to do though.
>

Thanks! I think I now understand how it's done. Sort of.

Devel::StrackTrace::WithLexicals uses PadWalker to create a hash of of all
the lexical variables for a given call frame. Eval::WithLexicals is then
passed that hash. By the way, this is similar to how Python's eval works.

And then comes the complicated part, Eval::WithLexicals uses that hash
somehow in a string eval. How this works is not obvious to me, but the next
couple of days I'll probably figure this out as I have a  good debugger
that can track nicely through string evals which is used a bit here.
Eval::WithLexicals (and Eval::WithLexicals::WithHintPersistence ) then
needs to put changed values back someplace. (Perhaps this id done via
B::svref_2object.)

So one thing that needs to be checked in my use is that the values do
indeed get put back into the right place in the call stack and not just say
in the hash created by Devel::StackTrace::WithLexicals.

Another thing that seems to be something that could go wrong is in handling
local variables, because PadWaker doesn't handle local variables.

Suppose I have a local variable $a defined in main and a couple of calls
down I have another local $a --alsi in package main::. I am not sure how I
would be able to access the outer or main-most $a to read the value.

(Actually here is a bad way and one that is sort of used in the first Ruby
debugger: On every call create a closure with all of the values. This is
horrendously slow.)

And looking at WithLexical.pm's code, there is this comment in
_record_caller_data():
# PadWalker ignores eval block and eval string so we must do so too.

So this could also be another source of discrepancy people may run into.

Given all of this -- and I am sorry if this was a bit long -- it seems that
life would be much simpler and more reliable if Perl just had a eval_n
function which did the evaluations n levels down the call stack.

Looking at the C code, one can get a PERL_CONTEXT from the call stack and
somehow one just needs to make sure that this is what is used by this new
eval_n routine.


RE: PadWalker, eval and perl5db

2011-11-23 Thread Brock
On Sun, 20 Nov 2011 Rocky Bernstein wrote:
> I've briefly looked at PadWalker which can look at "my" and "our"
> variables on a call stack. And while this is very useful, it is not
> the same as being able to evaluate a string in the context of a stack
> frame.
>
> Has anyone tried to create such an eval? A simple suggested interface
> would be to pass it an integer which indicates the call stack frame to
> use.

You might take a look at Eval::WithLexicals and how it is used in
Plack::Middleware::InteractiveDebugger (which, upon die(), lets the user
open a web-based REPL at any level of the call stack). Looks like there
is some manual work you have to do though.

--Brock



PadWalker, eval and perl5db

2011-11-20 Thread Rocky Bernstein
In working on the Trepanning debugger for Perl which in large part is
modernizing and modularizing perl5db, I keep running into the limitations
of eval.

In both Ruby and Python, one can pass arguments in addition to the string
to evaluate which controls the environment or context that evaluation uses.

Lacking this, evaluations in perl5db need to be done in the DB namespace -
but inside the "eval", one must first switch back to the debugged program
namespace, e.g. "main".

Consider what this does in debuggers that want to modularize code and move
code and modules out of the DB namespace. In the trepanning debugger there
is an object which is the command processor. It is pretty much a
self-contained read-eval-print loop. But the eval part of it has to go back
to DB any time an evaluation needs to be done. So some mechanism needed to
ping-pong values back and forth between the command loop and DB.

Another limitation of the Perl debuggers is that they can only evaluate
expressions which may contain "my" variables in the context of the point of
the stopped program, not call-stack frames further down.

I've briefly looked at PadWalker which can look at "my" and "our" variables
on a call stack. And while this is very useful, it is not the same as being
able to evaluate a string in the context of a stack frame.

Has anyone tried to create such an eval? A simple suggested interface would
be to pass it an integer which indicates the call stack frame to use.

Thanks.