View Issue Details

IDProjectCategoryView StatusLast Update
0001754XdebugCode Coveragepublic2022-11-05 09:51
Reporterjuancasanova Assigned Toderick  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionnot fixable 
Product Version2.9.2 
Summary0001754: Incorrect code coverage in nested ifs
Description

I have made a simple script like this:

<pre>

  1. if (true) {
  2. if (true) {
  3. $a = 0;
  4. } else {
  5. $b = 1;
  6. }
  7. } else {
  8. $c = 2;
  9. }
    </pre>

When using Xdebug's code coverage calculation, it shows that both lines 3 and 5 are beign executed although it is obviously impossible.

I have actually tested this with PHP 7.1.33, 7.2.28, 7.3.15 and 7.4.3 (all with Xdebug 2.9.2).

Steps To Reproduce

I have attached a small script that replicates the failure every time.

TagsNo tags attached.
Attached Files
test.php (178 bytes)   
<?php

xdebug_start_code_coverage();

if (true) {
    if (true) {
        $a = 0;
    } else {
        $b = 1;
    }
} else {
    $c = 2;
}

var_dump(xdebug_get_code_coverage());
test.php (178 bytes)   
Operating SystemUbuntu 18.0.4
PHP Version7.4.0-7.4.4

Activities

derick

2020-03-06 12:06

administrator   ~0005275

I've analysed your test file with vld, and that gives me the following output:

<pre>
compiled vars: !0 = $a, !1 = $b, !2 = $c
line #* E I O op fetch ext return operands

3 0 E > EXT_STMT
1 INIT_FCALL 'xdebug_start_code_coverage'
2 EXT_FCALL_BEGIN
3 DO_FCALL 0
4 EXT_FCALL_END
5 5 EXT_STMT
6 > JMPZ <true>, ->15
6 7 > EXT_STMT
8 > JMPZ <true>, ->12
7 9 > EXT_STMT
10 ASSIGN !0, 0
11 > JMP ->14
9 12 > EXT_STMT
13 ASSIGN !1, 1
14 > > JMP ->17
12 15 > EXT_STMT
16 ASSIGN !2, 2
15 17 > EXT_STMT
18 INIT_FCALL 'var_dump'
19 EXT_FCALL_BEGIN
20 INIT_FCALL 'xdebug_get_code_coverage'
21 EXT_FCALL_BEGIN
22 DO_FCALL 0 $7
23 EXT_FCALL_END
24 SEND_VAR $7
25 DO_FCALL 0
26 EXT_FCALL_END
27 > RETURN 1

</pre>

After the $a = 0 (line 7, opcode 10), PHP generates code to jump to the end of the whole if(true) { $a = 0 } else { $a = 1 } section. (line 7, opcode 11). PHP has generated a jump instruction to immediately jump away from that (line 9, opcode 14). Unfortunately, this means that for PHP's internals, there is now code being executed on line 9, even though when looking at the script, this makes no sense. Xdebug can't really change was PHP generates internally, so I'm having to close this as "Not Fixable". I'll see if I can talk to the PHP internals folks if they can see a way on how to fix this in PHP.

videoice

2022-11-05 09:51

reporter   ~0006437

the solution is to enable opcache for CLI (opcache.enable_cli=1), then the l5 and l8 are correctly pruned/excluded

Issue History

Date Modified Username Field Change
2020-03-05 09:29 juancasanova New Issue
2020-03-05 09:29 juancasanova File Added: test.php
2020-03-05 13:09 derick Description Updated
2020-03-06 12:06 derick Assigned To => derick
2020-03-06 12:06 derick Status new => resolved
2020-03-06 12:06 derick Resolution open => not fixable
2020-03-06 12:06 derick Note Added: 0005275
2022-11-05 09:51 videoice Note Added: 0006437