} /* }}} */
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:
zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
return;
}
- }
+ } while (++opline < op_array->opcodes + op_array->last);
}
/* }}} */
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;
} /* }}} */
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) /* {{{ */
--- /dev/null
+--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();