View Issue Details

IDProjectCategoryView StatusLast Update
0001287XdebugUncategorizedpublic2016-05-10 19:45
ReportereZH Assigned Toderick  
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionnot fixable 
Product Version2.4.0 
Summary0001287: Code coverage: foreach next cycle is reported as wrong line under PHP7
Description

See attached script.
End of foreach body line (closing curly brace) is reported as wrong line (expected line 10, but reported as line 8 containing "if" body line that is not executed

TagsNo tags attached.
Attached Files
b.php (525 bytes)   
<?php
xdebug_start_code_coverage();
foreach (['a', 'b'] as $item) {
    if ($item == 'c') {
        echo "c";
    }
    if ($item == 'd') {
        echo "d";
    }
}
$cc = xdebug_get_code_coverage()[__FILE__];
xdebug_stop_code_coverage();
$expected = [
    3 => 1,//foreach {
    4 => 1,//if ($item == 'c') {
    7 => 1,//if ($item == 'd') {
    10 => 1,//} endforeach
    11 => 1,//$cc = xdebug_get_code_coverage()[__FILE__];
];
assert($cc == $expected, print_r($cc, true) . ' is not equal to ' . print_r($expected, true));
b.php (525 bytes)   
Operating System
PHP Version7.0.0-7.0.4

Activities

derick

2016-05-10 19:45

administrator   ~0003591

You are right that Code Coverage shows the wrong line. Unfortunately, this is
something that is caused by PHP's internals and not Xdebug.

PHP generates for this code:

1 <?php
2 xdebug_start_code_coverage();
3 foreach (['a', 'b'] as $item) {
4 if ($item == 'c') {
5 echo "c";
6 }
7 if ($item == 'd') {
8 echo "d";
9 }
10 }
11 $cc = xdebug_get_code_coverage()[FILE];

The following opcodes:

line #* E I O op fetch ext return operands

2 0 E > EXT_STMT
1 INIT_FCALL 'xdebug_start_code_coverage'
2 EXT_FCALL_BEGIN
3 DO_FCALL 0
4 EXT_FCALL_END
3 5 EXT_STMT
6 > FE_RESET_R $3 <array>, ->19
7 > > FE_FETCH_R $3, !0, ->19
4 8 > EXT_STMT
9 IS_EQUAL 0000004:0000004 !0, 'c'
10 > JMPZ 0000004:0000004, ->13
5 11 > EXT_STMT
12 ECHO 'c'
7 13 > EXT_STMT
14 IS_EQUAL 0000004:0000004 !0, 'd'
15 > JMPZ 0000004:0000004, ->7
8 16 > EXT_STMT
17 ECHO 'd'
18 > JMP ->7
19 > FE_FREE $3
11 20 EXT_STMT
21 INIT_FCALL 'xdebug_get_code_coverage'
22 EXT_FCALL_BEGIN
23 DO_FCALL 0 $4
24 EXT_FCALL_END
25 FETCH_DIM_R $3 $4, '%2Ftmp%2Fb.php'
26 ASSIGN !1, $3

Opcode 19 (FE_FREE) is the end of the foreach, but as you can see PHP still
thinks this is on line 8. Because of this, Xdebug shows the wrong line,
although it's correct from its point of vision.

I recommend you file a bug report at http://bugs.php.net - and feel free to
link to this issue.

Issue History

Date Modified Username Field Change
2016-03-18 17:58 eZH New Issue
2016-03-18 17:58 eZH File Added: b.php
2016-05-10 19:45 derick Note Added: 0003591
2016-05-10 19:45 derick Status new => resolved
2016-05-10 19:45 derick Resolution open => not fixable
2016-05-10 19:45 derick Assigned To => derick
2016-07-31 12:36 derick Category Usage problems => Usage problems (Crashes)
2016-07-31 12:38 derick Category Usage problems (Crashes) => Usage problems (Wrong Results)
2020-03-12 16:35 derick Category Usage problems (Wrong Results) => Variable Display
2020-03-12 16:38 derick Category Variable Display => Uncategorized