diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 786a8f2db4b..cceea0ebb62 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -9680,6 +9680,20 @@ ZEND_VM_HELPER(zend_interrupt_helper, ANY, ANY) zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); + + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + + } + } ZEND_VM_ENTER(); } ZEND_VM_CONTINUE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 90551512ef4..7efe9b7a0ce 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3384,6 +3384,20 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_interrupt_he zend_timeout(); } else if (zend_interrupt_function) { zend_interrupt_function(execute_data); + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); + + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + + } + } ZEND_VM_ENTER(); } ZEND_VM_CONTINUE(); diff --git a/ext/pcntl/tests/bug81577.phpt b/ext/pcntl/tests/bug81577.phpt new file mode 100644 index 00000000000..fc85d9ca9ed --- /dev/null +++ b/ext/pcntl/tests/bug81577.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #81577: (Exceptions in interrupt handlers) +--SKIPIF-- + +--FILE-- +getMessage() , "\n"; + } +} +?> +--EXPECT-- +Exception : Signal +Exception : Signal +Exception : Signal +Exception : Signal +Exception : Signal diff --git a/ext/pcntl/tests/bug81577_2.phpt b/ext/pcntl/tests/bug81577_2.phpt new file mode 100644 index 00000000000..dca66e90d6b --- /dev/null +++ b/ext/pcntl/tests/bug81577_2.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #81577: (Exceptions in interrupt handlers: ADD_ARRAY_ELEMENT) +--SKIPIF-- + +--FILE-- +getMessage() , "\n"; +} +var_dump($a); +?> +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + bool(true) + [2]=> + int(2) +} diff --git a/ext/pcntl/tests/bug81577_3.phpt b/ext/pcntl/tests/bug81577_3.phpt new file mode 100644 index 00000000000..a26b4ae9189 --- /dev/null +++ b/ext/pcntl/tests/bug81577_3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #81577: (Exceptions in interrupt handlers: cleanup_live_vars) +--SKIPIF-- + +--XFAIL-- +leaks are not fixed yet +--FILE-- +getMessage() , "\n"; +} +?> +--EXPECT-- +Exception : Signal