From f2b8cdc5be2612f3dff014ededab1ce36f884069 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 17 Nov 2013 11:59:21 -0200 Subject: [PATCH] - Added finish/f command --- Changelog.md | 1 + phpdbg_help.c | 16 ++++++++++---- phpdbg_help.h | 2 ++ phpdbg_prompt.c | 59 ++++++++++++++++++++++++++++++++++--------------- phpdbg_prompt.h | 5 +++-- test.php | 17 ++++++++++++++ 6 files changed, 76 insertions(+), 24 deletions(-) diff --git a/Changelog.md b/Changelog.md index 43753383d2..5d82f633a5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ Version 0.0.2 0000-00-00 2. Added printers for class and method 3. Make uniform commands and aliases where possible 4. Include all alias information and sub-command information in help +5. Added finish/f command Version 0.0.1 2013-11-15 diff --git a/phpdbg_help.c b/phpdbg_help.c index 4526f9fa83..8ae9c9468f 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -65,6 +65,14 @@ PHPDBG_HELP(until) /* {{{ */ 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_header(); @@ -101,7 +109,7 @@ PHPDBG_HELP(print) /* {{{ */ phpdbg_notice("Commands"); { const phpdbg_command_t *print_command = phpdbg_print_commands; - + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); while (print_command && print_command->name) { if (print_command->alias) { @@ -159,7 +167,7 @@ PHPDBG_HELP(break) /* {{{ */ phpdbg_notice("Commands"); { const phpdbg_command_t *break_command = phpdbg_break_commands; - + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); while (break_command && break_command->name) { if (break_command->alias) { @@ -174,7 +182,7 @@ PHPDBG_HELP(break) /* {{{ */ } /* }}} */ PHPDBG_HELP(clean) /* {{{ */ -{ +{ phpdbg_help_header(); 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"); @@ -244,7 +252,7 @@ PHPDBG_HELP(list) /* {{{ */ phpdbg_notice("Commands"); { const phpdbg_command_t *list_command = phpdbg_list_commands; - + phpdbg_writeln("\tAlias\tCommand\t\tPurpose"); while (list_command && list_command->name) { if (list_command->alias) { diff --git a/phpdbg_help.h b/phpdbg_help.h index 363acf6f56..758e501b1a 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -41,6 +41,7 @@ PHPDBG_HELP(next); PHPDBG_HELP(run); PHPDBG_HELP(eval); PHPDBG_HELP(until); +PHPDBG_HELP(finish); PHPDBG_HELP(print); PHPDBG_HELP(break); 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(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(finish, "continue until the current function has returned", 'f'), PHPDBG_HELP_D(print, "printing allows inspection of the execution environment", 'p'), PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'), PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'), diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 91f5c39f85..ef041321f5 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -38,6 +38,7 @@ static PHPDBG_COMMAND(next); static PHPDBG_COMMAND(run); static PHPDBG_COMMAND(eval); static PHPDBG_COMMAND(until); +static PHPDBG_COMMAND(finish); static PHPDBG_COMMAND(print); static PHPDBG_COMMAND(break); static PHPDBG_COMMAND(back); @@ -52,24 +53,25 @@ static PHPDBG_COMMAND(quit); /* }}} */ /* {{{ command declarations */ 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(step, "step through execution", 's'), - PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'), - PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'), - PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'), - PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'), - PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands), - PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands), - PHPDBG_COMMAND_EX_D(back, "show trace", 't'), - PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands), - PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'), - PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'), - PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands), - PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'), - PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'), - PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'), - PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'), + PHPDBG_COMMAND_EX_D(step, "step through execution", 's'), + PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'), + PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'), + PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'), + PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'), + PHPDBG_COMMAND_EX_D(finish, "continue until reaches next line", 'f'), + PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands), + PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands), + PHPDBG_COMMAND_EX_D(back, "show trace", 't'), + PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands), + PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'), + PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'), + PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands), + PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'), + PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'), + PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'), + PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'), {NULL, 0, 0} }; /* }}} */ @@ -308,6 +310,11 @@ static PHPDBG_COMMAND(until) /* {{{ */ return PHPDBG_UNTIL; } /* }}} */ +static PHPDBG_COMMAND(finish) /* {{{ */ +{ + return PHPDBG_FINISH; +} /* }}} */ + static PHPDBG_COMMAND(run) /* {{{ */ { if (EG(in_execution)) { @@ -824,6 +831,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } break; + case PHPDBG_FINISH: case PHPDBG_UNTIL: case PHPDBG_NEXT: { if (!EG(in_execution)) { @@ -977,6 +985,7 @@ void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */ int last_step = 0; uint last_lineno; const char *last_file; + const zend_execute_data *last_exec = NULL, *last_prev_exec; #if PHP_VERSION_ID < 50500 if (EG(exception)) { @@ -1015,6 +1024,7 @@ zend_vm_enter: \ do {\ switch (last_step = phpdbg_interactive(TSRMLS_C)) {\ + case PHPDBG_FINISH:\ case PHPDBG_UNTIL:\ case PHPDBG_NEXT:{\ goto next;\ @@ -1028,13 +1038,21 @@ zend_vm_enter: /* skip possible breakpoints */ goto next; } - if (last_step == PHPDBG_UNTIL && last_file == execute_data->op_array->filename && last_lineno == execute_data->opline->lineno) { /* skip possible breakpoints */ 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 */ phpdbg_print_opline( @@ -1083,6 +1101,11 @@ next: last_lineno = execute_data->opline->lineno; 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); if (PHPDBG_G(vmret) > 0) { diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index f3839d0315..e4e45dd1c4 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -27,8 +27,9 @@ #define PHPDBG_STRL(s) s, sizeof(s)-1 -#define PHPDBG_NEXT 2 -#define PHPDBG_UNTIL 3 +#define PHPDBG_NEXT 2 +#define PHPDBG_UNTIL 3 +#define PHPDBG_FINISH 4 /** * Command Executor diff --git a/test.php b/test.php index ef786ca047..3733eda7e2 100644 --- a/test.php +++ b/test.php @@ -7,10 +7,27 @@ class phpdbg { } } +function test() { + $var = 1 + 1; + $var += 2; + $var <<= 3; + + $foo = function () {}; + + $foo(); + + return $var; +} + $dbg = new phpdbg(); $test = 1; var_dump( $dbg->isGreat("PHP Rocks !!")); + +test(); + +echo "it works!\n"; + ?> -- 2.40.0