- Added finish/f command

This commit is contained in:
Felipe Pena 2013-11-17 11:59:21 -02:00
parent 146520f045
commit f2b8cdc5be
6 changed files with 76 additions and 24 deletions

View file

@ -8,6 +8,7 @@ Version 0.0.2 0000-00-00
2. Added printers for class and method 2. Added printers for class and method
3. Make uniform commands and aliases where possible 3. Make uniform commands and aliases where possible
4. Include all alias information and sub-command information in help 4. Include all alias information and sub-command information in help
5. Added finish/f command
Version 0.0.1 2013-11-15 Version 0.0.1 2013-11-15

View file

@ -65,6 +65,14 @@ PHPDBG_HELP(until) /* {{{ */
return SUCCESS; return SUCCESS;
} /* }}} */ } /* }}} */
PHPDBG_HELP(finish) /* {{{ */
{
phpdbg_help_header();
phpdbg_writeln("While stepping through execution, or after a breakpoint, use the finish command to step back into the vm and continue until the current function has returned");
phpdbg_help_footer();
return SUCCESS;
} /* }}} */
PHPDBG_HELP(compile) /* {{{ */ PHPDBG_HELP(compile) /* {{{ */
{ {
phpdbg_help_header(); phpdbg_help_header();
@ -101,7 +109,7 @@ PHPDBG_HELP(print) /* {{{ */
phpdbg_notice("Commands"); phpdbg_notice("Commands");
{ {
const phpdbg_command_t *print_command = phpdbg_print_commands; const phpdbg_command_t *print_command = phpdbg_print_commands;
phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); phpdbg_writeln("\tAlias\tCommand\t\tPurpose");
while (print_command && print_command->name) { while (print_command && print_command->name) {
if (print_command->alias) { if (print_command->alias) {
@ -159,7 +167,7 @@ PHPDBG_HELP(break) /* {{{ */
phpdbg_notice("Commands"); phpdbg_notice("Commands");
{ {
const phpdbg_command_t *break_command = phpdbg_break_commands; const phpdbg_command_t *break_command = phpdbg_break_commands;
phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); phpdbg_writeln("\tAlias\tCommand\t\tPurpose");
while (break_command && break_command->name) { while (break_command && break_command->name) {
if (break_command->alias) { if (break_command->alias) {
@ -174,7 +182,7 @@ PHPDBG_HELP(break) /* {{{ */
} /* }}} */ } /* }}} */
PHPDBG_HELP(clean) /* {{{ */ PHPDBG_HELP(clean) /* {{{ */
{ {
phpdbg_help_header(); phpdbg_help_header();
phpdbg_writeln("While debugging you may experience errors because of attempts to redeclare classes, constants or functions"); phpdbg_writeln("While debugging you may experience errors because of attempts to redeclare classes, constants or functions");
phpdbg_writeln("Cleaning the environment cleans these tables, so that files can be recompiled without exiting phpdbg"); phpdbg_writeln("Cleaning the environment cleans these tables, so that files can be recompiled without exiting phpdbg");
@ -244,7 +252,7 @@ PHPDBG_HELP(list) /* {{{ */
phpdbg_notice("Commands"); phpdbg_notice("Commands");
{ {
const phpdbg_command_t *list_command = phpdbg_list_commands; const phpdbg_command_t *list_command = phpdbg_list_commands;
phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); phpdbg_writeln("\tAlias\tCommand\t\tPurpose");
while (list_command && list_command->name) { while (list_command && list_command->name) {
if (list_command->alias) { if (list_command->alias) {

View file

@ -41,6 +41,7 @@ PHPDBG_HELP(next);
PHPDBG_HELP(run); PHPDBG_HELP(run);
PHPDBG_HELP(eval); PHPDBG_HELP(eval);
PHPDBG_HELP(until); PHPDBG_HELP(until);
PHPDBG_HELP(finish);
PHPDBG_HELP(print); PHPDBG_HELP(print);
PHPDBG_HELP(break); PHPDBG_HELP(break);
PHPDBG_HELP(clean); PHPDBG_HELP(clean);
@ -61,6 +62,7 @@ static const phpdbg_command_t phpdbg_help_commands[] = {
PHPDBG_HELP_D(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r'), PHPDBG_HELP_D(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r'),
PHPDBG_HELP_D(eval, "access to eval() allows you to affect the environment during execution", 'E'), PHPDBG_HELP_D(eval, "access to eval() allows you to affect the environment during execution", 'E'),
PHPDBG_HELP_D(until, "continue until the program reaches a source line different than the current one", 'u'), PHPDBG_HELP_D(until, "continue until the program reaches a source line different than the current one", 'u'),
PHPDBG_HELP_D(finish, "continue until the current function has returned", 'f'),
PHPDBG_HELP_D(print, "printing allows inspection of the execution environment", 'p'), PHPDBG_HELP_D(print, "printing allows inspection of the execution environment", 'p'),
PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'), PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'),
PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'), PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'),

View file

@ -38,6 +38,7 @@ static PHPDBG_COMMAND(next);
static PHPDBG_COMMAND(run); static PHPDBG_COMMAND(run);
static PHPDBG_COMMAND(eval); static PHPDBG_COMMAND(eval);
static PHPDBG_COMMAND(until); static PHPDBG_COMMAND(until);
static PHPDBG_COMMAND(finish);
static PHPDBG_COMMAND(print); static PHPDBG_COMMAND(print);
static PHPDBG_COMMAND(break); static PHPDBG_COMMAND(break);
static PHPDBG_COMMAND(back); static PHPDBG_COMMAND(back);
@ -52,24 +53,25 @@ static PHPDBG_COMMAND(quit); /* }}} */
/* {{{ command declarations */ /* {{{ command declarations */
static const phpdbg_command_t phpdbg_prompt_commands[] = { static const phpdbg_command_t phpdbg_prompt_commands[] = {
PHPDBG_COMMAND_EX_D(exec, "set execution context", 'e'), PHPDBG_COMMAND_EX_D(exec, "set execution context", 'e'),
PHPDBG_COMMAND_EX_D(compile, "attempt to pre-compile execution context", 'c'), PHPDBG_COMMAND_EX_D(compile, "attempt to pre-compile execution context", 'c'),
PHPDBG_COMMAND_EX_D(step, "step through execution", 's'), PHPDBG_COMMAND_EX_D(step, "step through execution", 's'),
PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'), PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'),
PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'), PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'),
PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'), PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'),
PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'), PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'),
PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands), PHPDBG_COMMAND_EX_D(finish, "continue until reaches next line", 'f'),
PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands), PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands),
PHPDBG_COMMAND_EX_D(back, "show trace", 't'), PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands),
PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands), PHPDBG_COMMAND_EX_D(back, "show trace", 't'),
PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'), PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands),
PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'), PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'),
PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands), PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'),
PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'), PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands),
PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'), PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'),
PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'), PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'),
PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'), PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'),
PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'),
{NULL, 0, 0} {NULL, 0, 0}
}; /* }}} */ }; /* }}} */
@ -308,6 +310,11 @@ static PHPDBG_COMMAND(until) /* {{{ */
return PHPDBG_UNTIL; return PHPDBG_UNTIL;
} /* }}} */ } /* }}} */
static PHPDBG_COMMAND(finish) /* {{{ */
{
return PHPDBG_FINISH;
} /* }}} */
static PHPDBG_COMMAND(run) /* {{{ */ static PHPDBG_COMMAND(run) /* {{{ */
{ {
if (EG(in_execution)) { if (EG(in_execution)) {
@ -824,6 +831,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */
} }
break; break;
case PHPDBG_FINISH:
case PHPDBG_UNTIL: case PHPDBG_UNTIL:
case PHPDBG_NEXT: { case PHPDBG_NEXT: {
if (!EG(in_execution)) { if (!EG(in_execution)) {
@ -977,6 +985,7 @@ void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */
int last_step = 0; int last_step = 0;
uint last_lineno; uint last_lineno;
const char *last_file; const char *last_file;
const zend_execute_data *last_exec = NULL, *last_prev_exec;
#if PHP_VERSION_ID < 50500 #if PHP_VERSION_ID < 50500
if (EG(exception)) { if (EG(exception)) {
@ -1015,6 +1024,7 @@ zend_vm_enter:
\ \
do {\ do {\
switch (last_step = phpdbg_interactive(TSRMLS_C)) {\ switch (last_step = phpdbg_interactive(TSRMLS_C)) {\
case PHPDBG_FINISH:\
case PHPDBG_UNTIL:\ case PHPDBG_UNTIL:\
case PHPDBG_NEXT:{\ case PHPDBG_NEXT:{\
goto next;\ goto next;\
@ -1028,13 +1038,21 @@ zend_vm_enter:
/* skip possible breakpoints */ /* skip possible breakpoints */
goto next; goto next;
} }
if (last_step == PHPDBG_UNTIL if (last_step == PHPDBG_UNTIL
&& last_file == execute_data->op_array->filename && last_file == execute_data->op_array->filename
&& last_lineno == execute_data->opline->lineno) { && last_lineno == execute_data->opline->lineno) {
/* skip possible breakpoints */ /* skip possible breakpoints */
goto next; goto next;
} }
if (last_step == PHPDBG_FINISH) {
if (!(execute_data->prev_execute_data == last_exec
&& execute_data == last_prev_exec)) {
/* skip possible breakpoints */
goto next;
}
last_exec = NULL;
last_prev_exec = NULL;
}
/* not while in conditionals */ /* not while in conditionals */
phpdbg_print_opline( phpdbg_print_opline(
@ -1083,6 +1101,11 @@ next:
last_lineno = execute_data->opline->lineno; last_lineno = execute_data->opline->lineno;
last_file = execute_data->op_array->filename; last_file = execute_data->op_array->filename;
if (last_step == PHPDBG_FINISH && last_exec == NULL) {
last_exec = execute_data;
last_prev_exec = execute_data->prev_execute_data;
}
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);
if (PHPDBG_G(vmret) > 0) { if (PHPDBG_G(vmret) > 0) {

View file

@ -27,8 +27,9 @@
#define PHPDBG_STRL(s) s, sizeof(s)-1 #define PHPDBG_STRL(s) s, sizeof(s)-1
#define PHPDBG_NEXT 2 #define PHPDBG_NEXT 2
#define PHPDBG_UNTIL 3 #define PHPDBG_UNTIL 3
#define PHPDBG_FINISH 4
/** /**
* Command Executor * Command Executor

View file

@ -7,10 +7,27 @@ class phpdbg {
} }
} }
function test() {
$var = 1 + 1;
$var += 2;
$var <<= 3;
$foo = function () {};
$foo();
return $var;
}
$dbg = new phpdbg(); $dbg = new phpdbg();
$test = 1; $test = 1;
var_dump( var_dump(
$dbg->isGreat("PHP Rocks !!")); $dbg->isGreat("PHP Rocks !!"));
test();
echo "it works!\n";
?> ?>