]> granicus.if.org Git - php/commitdiff
Fix leave and finish
authorBob Weinand <bobwei9@hotmail.com>
Sat, 19 Sep 2015 12:57:21 +0000 (14:57 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Sat, 19 Sep 2015 12:57:36 +0000 (14:57 +0200)
sapi/phpdbg/phpdbg_prompt.c
sapi/phpdbg/tests/finish_leave_001.phpt [new file with mode: 0644]

index 41d221f5277c06df3d942e73656b511da799c217..2e0f4903f81c54435a22794206cc3dea7c432cfd 100644 (file)
@@ -565,11 +565,11 @@ PHPDBG_COMMAND(next) /* {{{ */
 } /* }}} */
 
 static void phpdbg_seek_to_end(void) /* {{{ */ {
-       const zend_op *opline = EG(current_execute_data)->opline;
-       const zend_op_array *op_array = &EG(current_execute_data)->func->op_array - 1;
+       const zend_op_array *op_array = &EG(current_execute_data)->func->op_array;
+       const zend_op *opline = op_array->opcodes;
 
        PHPDBG_G(seek_ex) = EG(current_execute_data);
-       while (++opline < op_array->opcodes + op_array->last) {
+       do {
                switch (opline->opcode) {
                        case ZEND_RETURN:
                        case ZEND_FAST_RET:
@@ -580,7 +580,7 @@ static void phpdbg_seek_to_end(void) /* {{{ */ {
                                zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
                                return;
                }
-       }
+       } while (++opline < op_array->opcodes + op_array->last);
 }
 /* }}} */
 
@@ -591,8 +591,12 @@ PHPDBG_COMMAND(finish) /* {{{ */
                return SUCCESS;
        }
 
-       PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
        phpdbg_seek_to_end();
+       if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) EG(current_execute_data)->opline)) {
+               zend_hash_clean(&PHPDBG_G(seek));
+       } else {
+               PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
+       }
 
        return PHPDBG_FINISH;
 } /* }}} */
@@ -604,10 +608,15 @@ PHPDBG_COMMAND(leave) /* {{{ */
                return SUCCESS;
        }
 
-       PHPDBG_G(flags) |= PHPDBG_IN_LEAVE;
        phpdbg_seek_to_end();
-
-       return PHPDBG_LEAVE;
+       if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) EG(current_execute_data)->opline)) {
+               zend_hash_clean(&PHPDBG_G(seek));
+               phpdbg_notice("leave", "type=\"end\"", "Already at the end of the function");
+               return SUCCESS;
+       } else {
+               PHPDBG_G(flags) |= PHPDBG_IN_LEAVE;
+               return PHPDBG_LEAVE;
+       }
 } /* }}} */
 
 PHPDBG_COMMAND(frame) /* {{{ */
diff --git a/sapi/phpdbg/tests/finish_leave_001.phpt b/sapi/phpdbg/tests/finish_leave_001.phpt
new file mode 100644 (file)
index 0000000..774776c
--- /dev/null
@@ -0,0 +1,41 @@
+--TEST--
+test finish and leave commands
+--PHPDBG--
+b bar
+b 5
+r
+finish
+leave
+leave
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at bar]
+prompt> [Breakpoint #1 added at %s:5]
+prompt> [Breakpoint #0 in bar() at %s:9, hits: 1]
+>00009:     return "world";
+ 00010: }
+ 00011: 
+prompt> [Breakpoint #1 at %s:5, hits: 1]
+>00005:     return ["hello", $other];
+ 00006: }
+ 00007: 
+prompt> [Breaking for leave at %s:5]
+>00005:     return ["hello", $other];
+ 00006: }
+ 00007: 
+prompt> [Already at the end of the function]
+prompt> 
+--FILE--
+<?php
+function foo() {
+    $other = bar();
+    
+    return ["hello", $other];
+}
+
+function bar() {
+    return "world";
+}
+
+foo();