summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c25
-rw-r--r--sapi/phpdbg/tests/finish_leave_001.phpt41
2 files changed, 58 insertions, 8 deletions
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 41d221f527..2e0f4903f8 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -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
index 0000000000..774776c05f
--- /dev/null
+++ b/sapi/phpdbg/tests/finish_leave_001.phpt
@@ -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();