]> granicus.if.org Git - php/commitdiff
- Added finish/f command
authorFelipe Pena <felipensp@gmail.com>
Sun, 17 Nov 2013 13:59:21 +0000 (11:59 -0200)
committerFelipe Pena <felipensp@gmail.com>
Sun, 17 Nov 2013 13:59:21 +0000 (11:59 -0200)
Changelog.md
phpdbg_help.c
phpdbg_help.h
phpdbg_prompt.c
phpdbg_prompt.h
test.php

index 43753383d2b33df53fbdd4c4df822b640d8de9c9..5d82f633a5bb42d0402bc6ecfdeffe27e84e2387 100644 (file)
@@ -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
index 4526f9fa834863f44c6ce914a48b01f5eaaf42d1..8ae9c9468fe8de00cc41304fc5e2c9b3721fe392 100644 (file)
@@ -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) {
index 363acf6f5615a8dd85c023023e2eb826674a6d76..758e501b1a73e7a17c02347f24237b4bbb494c03 100644 (file)
@@ -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'),
index 91f5c39f85bbb01332e51bc9eb36e74ac67d06cc..ef041321f5ac1b55de43ba36d07b0df196589a46 100644 (file)
@@ -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) {
index f3839d0315080fbd76a7830610251fdd10931a7a..e4e45dd1c4a0aeb42ecfd695830b726df4fd0f71 100644 (file)
@@ -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
index ef786ca047c1559380ae2388dbd3f039c82b381b..3733eda7e2f72c606990df185e0518655446da79 100644 (file)
--- 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";
+
 ?>