XDebug code coverage update - 14th July

[email protected] (Allister Beharry) Tue, 14 Jul 2009 15:36:11 -0400
Newsgroups php.pecl.dev,php.gsoc
Message-ID <[email protected]>
I haven't written a project update since June 7th but I have managed
to complete some of the objectives I had:
*I increased the resolution of Xdebug's counting process from the line
to the opline - so the individual ops for each line are now tracked
and counted. This is necessary for any kind of branch analysis. See
the example below.

* I've added counting decisions and branches. A decision is created by
control flow statements - if/else  for/do/while and the ? operator and
are usually implement by an IS_SMALLER and JMPNZ or JUMPZNZ
instruction. A branch occurs on whether the condition is true or false
- so there are two branches for every decision. My code keeps track of
where the branches occur and how many times they are actually
executed. Comtact me my xdebug build if anyone wants to try out the
new code - I'll also roll a patchfor2.0.5. Counting inside class
methods does not work or now but this
should be simple to implement as it will follow the pattern of
counting inside user functions.The function name '0' in the data
represents the top-level PHP script.

My tasks this week are:
*Add basic blocks info - breaking up a script into its basic block
allows code coverage programs to determine which parts of the script
were executed
*Add compatibility for existing programs using xdebug.  The data
structure returned by default by xdebug should not be changed, but by
the use of constants like XDEBUG_CC_BRANCH_ANALYSIS and
XDEBUG_CC_DUMP_INSTRUCTIONS the additional info will be returned

3. Discuss and start work on an API for the counting process - You
could expose a set of functions and data that can be used by other
code coverage code or extensions.

Example:
For the following script:
<?php
   xdebug_start_code_coverage();

   function a($a) {
       echo $a * 2.5;
   }

   function b($count) {
       for ($i = 0; $i < $count; $i++) {
           a($i + 0.17);
       }
   }

   b(6);
   b(10);

   var_dump(xdebug_get_code_coverage());
?>

this is the data structure created:
array(1) {
 ["E:\PHPDEV\test_scripts\func3_cc.php"]=>
 array(3) {
   [0]=>
   array(3) {
     ["lines"]=>
     array(7) {
       [2]=>
       array(4) {
         ["lineno"]=>
         int(2)
         ["count"]=>
         int(1)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(4) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [4]=>
       array(4) {
         ["lineno"]=>
         int(4)
         ["count"]=>
         int(1)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(2) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(3) "NOP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [8]=>
       array(4) {
         ["lineno"]=>
         int(8)
         ["count"]=>
         int(1)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(2) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(3) "NOP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [14]=>
       array(4) {
         ["lineno"]=>
         int(14)
         ["count"]=>
         int(1)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(5) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "SEND_VAL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [15]=>
       array(4) {
         ["lineno"]=>
         int(15)
         ["count"]=>
         int(1)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(5) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "SEND_VAL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [17]=>
       array(4) {
         ["lineno"]=>
         int(17)
         ["count"]=>
         int(0)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(8) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(1)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [5]=>
           array(5) {
             ["position"]=>
             int(5)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(15) "SEND_VAR_NO_REF"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [6]=>
           array(5) {
             ["position"]=>
             int(6)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [7]=>
           array(5) {
             ["position"]=>
             int(7)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
         }
       }
       [18]=>
       array(4) {
         ["lineno"]=>
         int(18)
         ["count"]=>
         int(0)
         ["executed"]=>
         int(0)
         ["instructions"]=>
         array(5) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(3) "NOP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(4) "ECHO"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(6) "RETURN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(21) "ZEND_HANDLE_EXCEPTION"
             ["dead"]=>
             int(1)
             ["executed"]=>
             int(0)
           }
         }
       }
     }
     ["total_branches"]=>
     int(0)
     ["branches_counted"]=>
     int(0)
   }
   ["a"]=>
   array(3) {
     ["lines"]=>
     array(3) {
       [4]=>
       array(4) {
         ["lineno"]=>
         int(4)
         ["count"]=>
         int(16)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(2) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(7) "EXT_NOP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(4) "RECV"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [5]=>
       array(4) {
         ["lineno"]=>
         int(5)
         ["count"]=>
         int(16)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(3) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(3) "MUL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(4) "ECHO"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [6]=>
       array(4) {
         ["lineno"]=>
         int(6)
         ["count"]=>
         int(0)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(3) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(6) "RETURN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(21) "ZEND_HANDLE_EXCEPTION"
             ["dead"]=>
             int(1)
             ["executed"]=>
             int(0)
           }
         }
       }
     }
     ["total_branches"]=>
     int(0)
     ["branches_counted"]=>
     int(0)
   }
   ["b"]=>
   array(3) {
     ["lines"]=>
     array(5) {
       [8]=>
       array(4) {
         ["lineno"]=>
         int(8)
         ["count"]=>
         int(2)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(2) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(7) "EXT_NOP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(4) "RECV"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [9]=>
       array(4) {
         ["lineno"]=>
         int(9)
         ["count"]=>
         int(16)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(8) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(6) "ASSIGN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(18)
             ["opcode name"]=>
             string(10) "IS_SMALLER"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(18)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(6) "JMPZNZ"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(0)
           }
           [5]=>
           array(5) {
             ["position"]=>
             int(5)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "POST_INC"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [6]=>
           array(5) {
             ["position"]=>
             int(6)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(4) "FREE"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [7]=>
           array(5) {
             ["position"]=>
             int(7)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(3) "JMP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [10]=>
       array(4) {
         ["lineno"]=>
         int(10)
         ["count"]=>
         int(16)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(6) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(15) "EXT_FCALL_BEGIN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(3) "ADD"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [3]=>
           array(5) {
             ["position"]=>
             int(3)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "SEND_VAL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [4]=>
           array(5) {
             ["position"]=>
             int(4)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(8) "DO_FCALL"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [5]=>
           array(5) {
             ["position"]=>
             int(5)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(13) "EXT_FCALL_END"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [11]=>
       array(4) {
         ["lineno"]=>
         int(11)
         ["count"]=>
         int(16)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(1) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(16)
             ["opcode name"]=>
             string(3) "JMP"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
         }
       }
       [12]=>
       array(4) {
         ["lineno"]=>
         int(12)
         ["count"]=>
         int(0)
         ["executed"]=>
         int(1)
         ["instructions"]=>
         array(3) {
           [0]=>
           array(5) {
             ["position"]=>
             int(0)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(8) "EXT_STMT"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [1]=>
           array(5) {
             ["position"]=>
             int(1)
             ["count"]=>
             int(2)
             ["opcode name"]=>
             string(6) "RETURN"
             ["dead"]=>
             int(0)
             ["executed"]=>
             int(1)
           }
           [2]=>
           array(5) {
             ["position"]=>
             int(2)
             ["count"]=>
             int(0)
             ["opcode name"]=>
             string(21) "ZEND_HANDLE_EXCEPTION"
             ["dead"]=>
             int(1)
             ["executed"]=>
             int(0)
           }
         }
       }
     }
     ["total_branches"]=>
     int(2)
     ["branches_counted"]=>
     int(2)
   }
 }
}