/* code may behave weirdly if EG(exception) is set */
#define DO_INTERACTIVE(allow_async_unsafe) do { \
+ const zend_op *backup_opline; \
if (exception) { \
+ if (EG(current_execute_data) && EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) { \
+ backup_opline = EG(current_execute_data)->opline; \
+ } \
++GC_REFCOUNT(exception); \
zend_clear_exception(); \
} \
case PHPDBG_UNTIL: \
case PHPDBG_NEXT: \
if (exception) { \
- Z_OBJ(zv) = exception; \
- zend_throw_exception_internal(&zv); \
+ if (EG(current_execute_data) && EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type) \
+ && (backup_opline->opcode == ZEND_HANDLE_EXCEPTION || backup_opline->opcode == ZEND_CATCH)) { \
+ EG(current_execute_data)->opline = backup_opline; \
+ EG(exception) = exception; \
+ } else { \
+ Z_OBJ(zv) = exception; \
+ zend_throw_exception_internal(&zv); \
+ } \
} \
/* fallthrough */ \
default: \
--- /dev/null
+--TEST--
+Stepping with exceptions must not be stuck at CATCH
+--PHPDBG--
+b ZEND_THROW
+r
+s
+
+
+
+
+
+
+q
+--EXPECTF--
+[Successful compilation of %s]
+prompt> [Breakpoint #0 added at ZEND_THROW]
+prompt> [Breakpoint #0 in ZEND_THROW at %s:4, hits: 1]
+>00004: throw new Exception;
+ 00005: }
+ 00006:
+prompt> [L0 %s HANDLE_EXCEPTION %s]
+>00004: throw new Exception;
+ 00005: }
+ 00006:
+prompt> [L0 %s HANDLE_EXCEPTION %s]
+[L9 %s CATCH "Exception" $e 1 %s]
+>00008: foo();
+ 00009: } catch (Exception $e) {
+ 00010: echo "ok";
+prompt> [L10 %s ECHO "ok" %s]
+>00010: echo "ok";
+ 00011: } finally {
+ 00012: echo " ... ok";
+prompt> ok
+[L10 %s FAST_CALL J8 ~1 %s]
+[L12 %s ECHO " ... ok" %s]
+>00012: echo " ... ok";
+ 00013: }
+ 00014:
+prompt> ... ok
+[L12 %s FAST_RET ~1 %s]
+[L10 %s JMP J10 %s]
+>00010: echo "ok";
+ 00011: } finally {
+ 00012: echo " ... ok";
+prompt> [L12 %s RETURN 1 %s]
+>00012: echo " ... ok";
+ 00013: }
+ 00014:
+prompt> [Script ended normally]
+prompt>
+--FILE--
+<?php
+
+function foo() {
+ throw new Exception;
+}
+
+try {
+ foo();
+} catch (Exception $e) {
+ echo "ok";
+} finally {
+ echo " ... ok";
+}