|
Posted by giblfiz on 01/07/08 19:43
I'm trying to write an "introspective debugger" file. (it's tempting
to use the word class, but it's just not true.) The idea being that
you include the file at the beginning of your all ready written code,
add a few STOP statements, and then visit you script as normal. Only
now you get a simple ajax debugger which lets you view source files,
your stack, step through the code, resume operation (to next STOP),
and watch variables.
Sounds impossible? Sounds insane? Using some of the less well known
PHP functions, and some tricks with sockets I have figured out how to
do all of this except for watching variables that are not globals.
(take a look at register_tick_function, and at debug_backtrace and
then think about it for a few seconds, most of what I'm talking about
is actually in there)
So in answer to your question, no I CAN'T modify a(), because a() is
actually pretty much every function in the program. (since b() is
being called on every tick, from every function and every method) I
should have realized that by putting that a() b() example into place
people were going to assume that it was actually my situation. My
actual situation is:
<?php
register_tick_function("ticker");
ticker(){
$my_var_in_ticker_scope = "known value";
var_dump(get_defined_vars());
var_dump(debug_backtrace());
}
declare(ticks=1);
a(){
$my_a = "mystery value";
1+1;
}
a();
?>
So there is a point, right about when 1+1 is being run, when ticker
will be called and its results will be:
A dump of all the variables in the global scope, and
$my_var_in_ticker_scope, and a dump of the stack which will more or
less say:
2) Ticker()
1) a()
My best bet before was trying
register_tick_function(Ticker,get_defined_vars()), but this evaluates
get_defined_vars() once, when register_tick_function is called, not
every time ticker gets called. (this behavior seems obvious to me in
retrospect, but maybe someone knows how force it to be re-evaluated on
a run by run basis. nothing I know of in the language can do this)
Right now I have three "best bets":
1) Possibly throwing a user defined error, and then seeing what scopes
can be reached as part of a user defined error handler. (I haven't
played with this yet, but it strikes me as a longshot)
2) A similar idea using throw and catch. I am even less enthusiastic
about this idea because it pulls you down out of your current scope in
an unrecoverable way. But if there is a way to register a catch block
that is universal, that would work.
3) Perhaps there is something really interesting that can be done
using eval. I haven't really thought about it too deeply yet.
I'm also open to any other ideas, if anyone has any.
[Back to original message]
|