From d3560b7169a828919835b99a07c267fed297f6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 8 Aug 2024 16:54:14 +0200 Subject: [PATCH 2/2] Exit coverage --- src/coverage/code_coverage.c | 40 +++++++++++++++++++++++++++++ tests/coverage/coverage_exit.inc | 12 +++++++++ tests/coverage/coverage_exit.phpt | 42 +++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 tests/coverage/coverage_exit.inc create mode 100644 tests/coverage/coverage_exit.phpt diff --git a/src/coverage/code_coverage.c b/src/coverage/code_coverage.c index fbf9f48d..4ec29660 100644 --- a/src/coverage/code_coverage.c +++ b/src/coverage/code_coverage.c @@ -367,6 +367,46 @@ static int xdebug_find_jumps(zend_op_array *opa, unsigned int position, size_t * jumps[0] = XDEBUG_JMP_EXIT; *jump_count = 1; return 1; + } else if ( + opcode.opcode == ZEND_INIT_FCALL + ) { + zval *func_name = RT_CONSTANT(&opa->opcodes[position], opcode.op2); + if (zend_string_equals_literal(Z_PTR_P(func_name), "exit")) { + int level = 0; + uint32_t start = position + 1; + + for (;;) { + switch (opa->opcodes[start].opcode) { + case ZEND_INIT_FCALL: + case ZEND_INIT_FCALL_BY_NAME: + case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: + case ZEND_INIT_USER_CALL: + case ZEND_INIT_METHOD_CALL: + case ZEND_INIT_STATIC_METHOD_CALL: + case ZEND_INIT_PARENT_PROPERTY_HOOK_CALL: + case ZEND_NEW: + level++; + break; + case ZEND_DO_FCALL: + case ZEND_DO_FCALL_BY_NAME: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + if (level == 0) { + goto done; + } + level--; + break; + } + start++; + } + done: + ZEND_ASSERT(opa->opcodes[start].opcode == ZEND_DO_ICALL); + jumps[0] = XDEBUG_JMP_EXIT; + *jump_count = 1; + return 1; + } + } else if ( opcode.opcode == ZEND_MATCH || opcode.opcode == ZEND_SWITCH_LONG || diff --git a/tests/coverage/coverage_exit.inc b/tests/coverage/coverage_exit.inc new file mode 100644 index 00000000..3b0d5f33 --- /dev/null +++ b/tests/coverage/coverage_exit.inc @@ -0,0 +1,12 @@ + 2) { + exit; + + echo "foo"; + } +} + +exit_test(); +?> diff --git a/tests/coverage/coverage_exit.phpt b/tests/coverage/coverage_exit.phpt new file mode 100644 index 00000000..354944ad --- /dev/null +++ b/tests/coverage/coverage_exit.phpt @@ -0,0 +1,42 @@ +--TEST-- +Dummy +--SKIPIF-- + +--INI-- +xdebug.mode=coverage +xdebug.trace_options=0 +xdebug.collect_return=0 +xdebug.collect_assignments=0 +xdebug.auto_profile=0 +xdebug.dump_globals=0 +xdebug.trace_format=0 +--FILE-- + +--EXPECT-- +exit_test +- branches + - 00; OP: 00-06; line: 04-04 HIT; out1: 07 X ; out2: 12 HIT + - 07; OP: 07-08; line: 05-05 X ; out1: EX X + - 12; OP: 12-13; line: 09-09 HIT; out1: EX X +- paths + - 0 7: X + - 0 12: HIT + +{main} +- branches + - 00; OP: 00-03; line: 11-13 HIT; out1: EX X +- paths + - 0: HIT -- 2.40.1