Difference between revisions of "Brcov Predefined Probe"

From OC Systems Wiki!
Jump to: navigation, search
m (A simple example)
m (Example D-3. Branch Coverage Summary Report)
 
(21 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
== Branch Coverage Predefined Probe: brcov.ual ==
 
== Branch Coverage Predefined Probe: brcov.ual ==
  
'''NOTE:''' This predefined probe is still under development and not all features and platforms are supported.
+
'''NOTE:''' This predefined probe was developed as a prototype.  As of Aprobe version 4.4.9 the branch coverage features are available in the [[Coverage_Predefined_Probe|coverage.ual]]  predefined probe.  See [[Coverage_Predefined_Probe|coverage.ual]] for more information.
 +
 
 +
'''NOTE:''' This description is current for Aprobe version 4.4.8, 8 January 2018.  The current version of this probe should be run with the '''coverage.ual''' to provide the line and function coverage information.  Furthermore, <code>coverage.ual</code> should be configured to select the same functions as '''brcov.ual''' and should use the <code>ProduceBrcovOutput</code> option to produce compatible data to merge with '''brcov.ual'''.    Eventually, '''brcov.ual''' will be a stand-alone probe.
  
 
The '''brcov.ual''' predefined probe supports branch coverage analysis on user applications. Branch coverage tells you exactly which branches within a function were actually hit during program execution. This allows you to develop unit test cases which can be used to confirm that all the branches of code you have written are executed and taken.
 
The '''brcov.ual''' predefined probe supports branch coverage analysis on user applications. Branch coverage tells you exactly which branches within a function were actually hit during program execution. This allows you to develop unit test cases which can be used to confirm that all the branches of code you have written are executed and taken.
Line 9: Line 11:
 
But it should be noted that it is in testing these tricky cases that Aprobe can especially useful, since you as a user can write a probe that modifies the data on_entry to a function to force a specific path through the function, without worrying about how to get the normal caller of that function to pass that erroneous data.
 
But it should be noted that it is in testing these tricky cases that Aprobe can especially useful, since you as a user can write a probe that modifies the data on_entry to a function to force a specific path through the function, without worrying about how to get the normal caller of that function to pass that erroneous data.
  
You can find an example that works through some of the issues that arise from using Aprobe to do this in the <code>$APROBE/examples/learn/branch_coverage</code> directory. Additionally you are encouraged to contact OC Systems to discuss using Aprobe on your specific application.
+
Below is an example that works through some of the issues that arise from using Aprobe to do this.  It is based on the '''coverage.ual''' example in the <code>$APROBE/examples/learn/coverage</code> directory. Additionally you are encouraged to contact OC Systems to discuss using Aprobe on your specific application.
  
 
=== Usage ===
 
=== Usage ===
Line 23: Line 25:
 
A snapshot of the current state of collected branch coverage data may be written to the [[AUG_Files_Reference#Apd_File|APD file]] while the program is running (see [[#Configuration of Snapshots|Configuration of Snapshots]]). Taking such periodic snapshots at known events, like the entry to or exit from a particular function, may help correlate state data with the execution path recorded by the brcov probe. A final snapshot occurs automatically at program termination.
 
A snapshot of the current state of collected branch coverage data may be written to the [[AUG_Files_Reference#Apd_File|APD file]] while the program is running (see [[#Configuration of Snapshots|Configuration of Snapshots]]). Taking such periodic snapshots at known events, like the entry to or exit from a particular function, may help correlate state data with the execution path recorded by the brcov probe. A final snapshot occurs automatically at program termination.
  
After the application program terminates, the [[AUG_Tools_Reference#apformat|apformat]] command must be run to produce an XML branch coverage '''.brc''' file from the collected data. Use the [[AUG_Tools_Reference#abrmerge|abrmerge]] tool to produce reports and from the '''.brc''' files.  Data from multiple runs may be merged into a single '''.brc''' file and a single report using [[AUG_Tools_Reference#abrmerge|Abrmerge]] (see [[#Abrcmerge|'''abrcmerge''']] below).  Coverage data from '''brcov.ual''' and [[Coverage_Predefined_Probe|coverage.ual]] can be combined using [[AUG_Tools_Reference#abrmerge|Abrmerge]] to produce very extensive reports.
+
After the application program terminates, the [[AUG_Tools_Reference#apformat|apformat]] command must be run to produce an XML branch coverage '''.brc''' file from the collected data. Use the [[AUG_Tools_Reference#abrmerge|abrmerge]] tool to produce reports and from the '''.brc''' files.  Data from multiple runs may be merged into a single '''.brc''' file and a single report using [[AUG_Tools_Reference#abrmerge|abrmerge]] (see [[#Abrcmerge|'''abrcmerge''']] below).  Coverage data from '''brcov.ual''' and [[Coverage_Predefined_Probe|coverage.ual]] can be combined using [[AUG_Tools_Reference#abrmerge|Abrmerge]] to produce very extensive reports.
  
The report produced by the [[AUG_Tools_Reference#abrmerge|abrcmerge]] consists of several parts: the "Overall Summary," the "Subprogram Summary," the "Subprogram Details," and the "Source Annotation." (A ''subprogram'' is another name for a function, procedure, subroutine -- any callable entity.) The summaries lists the total lines and branches in the subprogram, how many lines/branches were not instrumented nor executed, and the percentage of instrumented lines/branches that were executed for the subprogram. The details section reports whether the subprogram was called, and if it was, it will report how many of the instrumented lines/branches were executed. In cases where coverage is less than 100% for a particular subprogram, the Details section will also list instrumented lines/branches which were not executed. The source section will annotate any provided source files with branch/line coverage information which will assist with test case creation.  Some parts of the report are options.  The coverage report will look similar to that in [[#Branch Coverage Summary Report|Branch Coverage Summary Report]].
+
The report produced by the [[AUG_Tools_Reference#abrmerge|abrcmerge]] consists of several parts: the "Overall Summary," the "Subprogram Summary," the "Subprogram Details," and the "Source Annotation." (A ''subprogram'' is another name for a function, procedure, subroutine -- any callable entity.) The summaries list the total lines and branches in the subprogram, how many lines/branches were not instrumented nor executed, and the percentage of instrumented lines/branches that were executed for the subprogram. The details section reports whether the subprogram was called, and if it was, it will report how many of the instrumented lines/branches were executed. In cases where coverage is less than 100% for a particular subprogram, the details section will also list instrumented lines/branches which were not executed. The source section will annotate any provided source files with branch/line coverage information which will assist with test case creation.  Some parts of the report are options.  The branch coverage report will look similar to that in [[#Branch Coverage Summary Report|Branch Coverage Summary Report]].
  
 
=== Branch Coverage UAL Parameters ===
 
=== Branch Coverage UAL Parameters ===
Line 31: Line 33:
 
'''brcov.ual''' is specified on the [[AUG_Tools_Reference#aprobe|'''aprobe''']] command line or in an [[AUG_Files_Reference#APO_File|'''APO file''']], and with [[AUG_Tools_Reference#apformat|'''apformat''']]. The specific options are:
 
'''brcov.ual''' is specified on the [[AUG_Tools_Reference#aprobe|'''aprobe''']] command line or in an [[AUG_Files_Reference#APO_File|'''APO file''']], and with [[AUG_Tools_Reference#apformat|'''apformat''']]. The specific options are:
  
  aprobe  -u brcov[.ual]    [-p " [-c config_filename] [-h] [-v]"  your_program  
+
  aprobe  -u brcov[.ual]    [-p " [-c config_filename] [-o data_filename] [-f name_len] [-h] [-v]"  your_program  
  
 
For example:
 
For example:
Line 42: Line 44:
 
; '''-c ''config_filename'''''
 
; '''-c ''config_filename'''''
 
: <br />specifies that the name of the probe configuration options file will follow immediately after -c. The default file name is your_program.brcov.cfg. For example, if your executable program is called wilbur.exe, then the default file name would be wilbur.exe.brcov.cfg.
 
: <br />specifies that the name of the probe configuration options file will follow immediately after -c. The default file name is your_program.brcov.cfg. For example, if your executable program is called wilbur.exe, then the default file name would be wilbur.exe.brcov.cfg.
 +
; '''-f ''name_len'''''
 +
: <br />truncates function names to the specified length.
 
; '''-h '''
 
; '''-h '''
 
: produces brief help text.
 
: produces brief help text.
 +
; '''-o ''data_filename'''''
 +
: <br />specifies the name for the branch coverage data file created during execution. The default file name is your_program.brc. For example, if your executable program is called wilbur.exe, then the default file name would be wilbur.exe.brc.
 
; '''-v '''
 
; '''-v '''
 
: verbose mode, which produces additional progress messages.
 
: verbose mode, which produces additional progress messages.
  
Note that if you use no UAL parameters, you need not specify UAL names at all. For example:
+
Note that if you use no UAL parameters, you need not specify UAL names to apformat. For example:
  
 
  apformat progname
 
  apformat progname
Line 55: Line 61:
 
=== Branch Coverage Configuration File ===
 
=== Branch Coverage Configuration File ===
  
The Branch Coverage configuration file is used to specify what subprograms are to be analyzed, when snapshots are to be taken, and other options, as described in [[Probe_Configuration_File|Configuration File]]. The example below shows one possible Branch Coverage configuration file.
+
The Branch Coverage configuration file is used to specify what subprograms are to be analyzed, when snapshots are to be taken, and other options, as described in [[AUG_Predefined_Probes#Probe_Configuration_File|Configuration File]]. The example below shows one possible Branch Coverage configuration file.
  
 
  PROBE CONFIGURATION FILE FOR BRCOV VERSION 1.0.0
 
  PROBE CONFIGURATION FILE FOR BRCOV VERSION 1.0.0
Line 78: Line 84:
 
The following are the only valid keywords that identify lines to set configuration variables. Each such line must begin with one of these keywords, and the keyword must be followed by a value. Nothing else is allowed on the same line.
 
The following are the only valid keywords that identify lines to set configuration variables. Each such line must begin with one of these keywords, and the keyword must be followed by a value. Nothing else is allowed on the same line.
  
==== CoverageEnabledInitially ====
+
===== CoverageEnabledInitially =====
  
 
This must be followed by the value TRUE or FALSE. The default is TRUE which indicates that data logging will begin as soon as the application program starts running. If set to FALSE, data logging will begin only after a call is made to the probe's function ap_Brcov_Enable(), rather than as soon as the application program starts running.
 
This must be followed by the value TRUE or FALSE. The default is TRUE which indicates that data logging will begin as soon as the application program starts running. If set to FALSE, data logging will begin only after a call is made to the probe's function ap_Brcov_Enable(), rather than as soon as the application program starts running.
  
==== ShowAllSnapshots ====
+
===== ShowAllSnapshots =====
 
                                                    
 
                                                    
 
This must be followed by TRUE or FALSE. The default is FALSE.  When FALSE, the data from all intermediate snapshots are rolled into the one final report.  When TRUE the data for every snapshot will be reported in separate summaries.
 
This must be followed by TRUE or FALSE. The default is FALSE.  When FALSE, the data from all intermediate snapshots are rolled into the one final report.  When TRUE the data for every snapshot will be reported in separate summaries.
  
==== ResetSnapshotCounts ====
+
===== ResetSnapshotCounts =====
 
                                                    
 
                                                    
 
This must be followed by TRUE or FALSE. The default is FALSE.  When FALSE, the data from all intermediate snapshots accumulate into the one final report.  When TRUE the counts are reset for each separate snapshot.
 
This must be followed by TRUE or FALSE. The default is FALSE.  When FALSE, the data from all intermediate snapshots accumulate into the one final report.  When TRUE the counts are reset for each separate snapshot.
  
==== ShowUnconditionalBranches ====
+
===== ShowUnconditionalBranches =====
  
 
This must be followed by TRUE or FALSE. The default is FALSE, which indicates that unconditional branches will not be tracked.  In general, conditional branches are more interesting than unconditional branches.
 
This must be followed by TRUE or FALSE. The default is FALSE, which indicates that unconditional branches will not be tracked.  In general, conditional branches are more interesting than unconditional branches.
Line 98: Line 104:
 
Each function for which branch coverage data is to be collected must be specified explicitly using the '''COVERAGE''', '''COVERFILE''', or '''COVERUNIT''' keywords.
 
Each function for which branch coverage data is to be collected must be specified explicitly using the '''COVERAGE''', '''COVERFILE''', or '''COVERUNIT''' keywords.
  
The '''COVERAGE''' keyword is followed by the name of the function, as described in [[AUG_Predefined_Probe#Configuration of Selected Functions|Configuration of Selected Functions]].  This directive selects specific functions by name (with possible wildcards).
+
The '''COVERAGE''' keyword is followed by the name of the function, as described in [[AUG_Predefined_Probes#Configuration of Selected Functions|Configuration of Selected Functions]].  This directive selects specific functions by name (with possible wildcards).
  
 
The '''COVERFILE''' keyword is followed by the name of a file and an option module name.  This keyword selects the functions originating from the designated source file (with possible wildcards).
 
The '''COVERFILE''' keyword is followed by the name of a file and an option module name.  This keyword selects the functions originating from the designated source file (with possible wildcards).
Line 122: Line 128:
 
* '''IS''' - This optional special identifier must be followed by an (arbitrarily long) string enclosed within quotation marks (""). It specifies a textual description or title that is to be logged along with the snapshot.
 
* '''IS''' - This optional special identifier must be followed by an (arbitrarily long) string enclosed within quotation marks (""). It specifies a textual description or title that is to be logged along with the snapshot.
  
=== Test Coverage API ===
+
Here is an example of a '''SNAPSHOT''' directive:
 +
 
 +
SNAPSHOT "my_function" ON EXIT IS "my on exit snapshot"
 +
 
 +
A snapshot may also be taken dynamically from a custom probe by calling the ap_Brcov_DoSnapshot function provided by the test coverage API.
 +
 
 +
==== Configuration of TestNames ====
 +
 
 +
The branch coverage probe configuration file allows you to specify the name of some subprograms for which test names can be set. This is done with lines beginning with the keyword '''TESTNAME'''.
 +
 
 +
Each '''TESTNAME''' line must specify a particular subprogram in the usual manner, just as is done for a '''COVERAGE''' line.
 +
 
 +
The remainder of the '''TESTNAME''' line contains pairs, where each pair has a special identifier keyword followed by its own associated value. These pairs give supplementary information about the test name change.
 +
 
 +
* '''ON''' - This optional special identifier must be followed by the value '''ENTRY''' or '''EXIT''', to denote that the test name is to be set on entry to or exit from the subprogram respectively.
 +
 
 +
* '''IS''' - This optional special identifier must be followed by an (arbitrarily long) string enclosed within quotation marks (""). It specifies a test name that is to be logged along with the snapshot.
 +
 
 +
Here is an example of a '''TESTNAME''' directive:
 +
 
 +
TESTNAME "my_function" ON ENTRY IS "test 1"
 +
 
 +
==== Configuration of TestName Hook Function ====
 +
 
 +
The branch coverage probe configuration file allows you to specify the name of some subprograms which are called when test name changes.  The designated function should have a single (in) parameter which is a pointer to a nil-terminated string which is the test name.  A value of NULL indicates no test name.
 +
 
 +
Each '''TESTNAMEHOOK''' line must specify a particular subprogram in the usual manner, just as is done for a '''COVERAGE''' line.
 +
 
 +
Here is an example of a '''TESTNAMEHOOK''' directive:
 +
 
 +
TESTNAMEHOOK "my_function"
 +
 
 +
If your test driver does not conform to the requirements of TESTNAME or TESTNAMEHOOK, you may write a custom probe using the ap_Brcov_SetTestName function provided by the Branch Coverage API.
 +
 
 +
=== Branch Coverage API ===
  
 
Users can control the behavior of the coverage probe by calls from within their own probes. The API for the trace probe is defined by [../include/coverage.h <code>$APROBE/include/brcov.h</code>]. Some of the functions exported by '''brcov.ual''' are:
 
Users can control the behavior of the coverage probe by calls from within their own probes. The API for the trace probe is defined by [../include/coverage.h <code>$APROBE/include/brcov.h</code>]. Some of the functions exported by '''brcov.ual''' are:
Line 129: Line 169:
 
* '''ap_Brcov_Disable''' - Disables logging of coverage data.
 
* '''ap_Brcov_Disable''' - Disables logging of coverage data.
 
* '''ap_Brcov_DoSnapshot''' - Dumps current coverage information.
 
* '''ap_Brcov_DoSnapshot''' - Dumps current coverage information.
 
+
* '''ap_Brcov_SetTestName''' - Sets the test name driving the current branch/edge coverage.
See [[#Snapshots|Snapshots]] for more information and an example.
 
  
 
=== Branch Coverage Performance Issues ===
 
=== Branch Coverage Performance Issues ===
  
See [[AUG_Predefined_Probe#Performance Issues|Performance Issues]] for a general discussion of factors that affect performance.
+
See [[AUG_Predefined_Probes#Performance Issues|Performance Issues]] for a general discussion of factors that affect performance.
  
 
The branch coverage probe is applied to the functions specified in the configuration file, so the run-time overhead is directly proportional to the number of calls to the functions selected and the number of branches executed in each function. The branch coverage probe simply increments an integer for each branch executed, so the amount of data is a constant multiple of the number of branches being covered, though additional snapshots increase this.
 
The branch coverage probe is applied to the functions specified in the configuration file, so the run-time overhead is directly proportional to the number of calls to the functions selected and the number of branches executed in each function. The branch coverage probe simply increments an integer for each branch executed, so the amount of data is a constant multiple of the number of branches being covered, though additional snapshots increase this.
Line 148: Line 187:
 
=== A simple example ===
 
=== A simple example ===
  
This example of the '''brcov.ual''' (and '''coverage.ual) predefined probe can be found in <code>$APROBE/examples/predefined_probes/brcov</code>.
+
The test application is very simple. It just prints out a mini-menu and waits for you to select 1 or 2. Depending on your selection, it does one of two actions. You can see this in the DoProcessing() function in <code>coverage_example.c</code>. We want to exercise every branch in this function -- we refer to this as getting 100% coverage.
  
The test application is very simple. It just prints out a mini-menu and waits for you to select 1 or 2. Depending on your selection, it does one of two actions. You can see this in the DoProcessing() function in coverage_example.c. We want to exercise every branch in this function -- we refer to this as getting 100% coverage.
+
Here is <code>coverage_example.c</code> which should be saved in the local directory:
 +
<pre>
 +
/* This is a simple example to demonstrate using brcov.ual with coverage.ual */
 +
#include <stdio.h>
 +
#include <stdlib.h>
  
 +
/* This is the function we are interested in. */
 +
void DoProcessing (void)
 +
{
 +
  int  Option = 0;
 +
  char Buffer [100];
 +
 
 +
  printf ("1. Print string #1\n");
 +
  printf ("2. Print string #2\n");
 +
 
 +
  while (Option < 1 || Option > 2)
 +
  {
 +
      printf ("      Enter your choice (1 or 2): \n");
 +
      fgets (Buffer, 99, stdin);
 +
      Option = atoi (Buffer);
 +
  }
 +
     
 +
  switch (Option)
 +
  {
 +
  case 1:
 +
      printf ("This is string #1 - pretty exciting, huh?!\n");
 +
      break;
 +
 +
  case 2:
 +
      printf ("This is string #2 - it doesn't get any better than this!\n");
 +
      break;
 +
  }
 +
}
 +
 +
int main (int argc, char **argv)
 +
{
 +
  DoProcessing ();
 +
  return 0;
 +
}
 +
</pre>
 
Note that, unlike some other uses of Aprobe, branch and line coverage requires you to be familiar with (the lines in) your source code to make most effective use of the probe.
 
Note that, unlike some other uses of Aprobe, branch and line coverage requires you to be familiar with (the lines in) your source code to make most effective use of the probe.
  
As before, we'll use make to build the example application:
+
We can build the example as follows:
 +
<pre>
 +
cc -g -v -o coverage_example coverage_example.c
 +
</pre>
  
  cd $APROBE/examples/predefined_probes/brcov
+
'''Note:''' We need to create a configuration file for '''coverage.ual''' to direct it to produce coverage data compatible with '''brcov.ual.'''  Create the following file <code>coverage_example.coverage.cfg</code> in the local directory:
  make
+
<pre>
  aprobe -u brcov -u coverage coverage_example
+
PROBE CONFIGURATION FILE FOR COVERAGE VERSION 2.0.0
 +
   
 +
ProduceBrcovData TRUE
 +
   
 +
COVERAGE "main"
 +
</pre>
 +
 
 +
We can run the example as follows:
 +
<pre>
 +
aprobe -u brcov -u coverage coverage_example
 +
</pre>
  
 
When the example application prompts you for a choice, enter the number 1. That will print out the first string and then the application will exit normally.
 
When the example application prompts you for a choice, enter the number 1. That will print out the first string and then the application will exit normally.
  
As before, aprobe stored the data in .apd files, so use apformat to format it:
+
As before, '''aprobe''' stored the data in .apd files, so use '''apformat''' to format it:
 +
<pre>
 +
apformat coverage_example
 +
</pre>
  
apformat coverage_example
+
and '''abrmerge''' to merge and view it:
 +
<pre>
 +
abrmerge *.brc *.c
 +
</pre>
  
and abrmerge to merge and view it:
+
Here's a portion of the report showing the line and branch coverage we've achieved:
 +
<pre>
 +
pkg.adb:
  
abrmerge *.brc *.c
 
 
Here's a portion of the report showing the line and branch coverage we've achieved:
 
  
<pre>
+
+  - This line/branch/edge was not executed.
coverage_example.c:
+
.  - This internal branch/edge was not executed but may not be significant.
 +
*  - This line/branch/edge was not probed.
  
   Line    Br O/I/T/N    Line Cnt  Source
+
   Line    Edge/Branch  Line Cnt  Source
 
   ------  -----------  ---------  ------- - -
 
   ------  -----------  ---------  ------- - -
       1 :              :        : /* This is a simple example to demonstrate using coverage.ual */
+
       1 :              :        :  
       2 :              :        : #include <stdio.h>
+
       2 :              :        : with Text_Io;
       3 :              :        : #include <stdlib.h>
+
       3 :              :        :  
       4 :              :        :  
+
       4 :              :        : package body pkg is
       5 :              :        : /* This is the function we are interested in. */
+
       5 :              :        :  
       6 :              :        : void DoProcessing (void)
+
       6 :              :        :   function Ident(i : integer) return integer is
       7 :              :     1 : {
+
       7 :              :       :   begin
       8 :              :      1 :    int  Option = 0;
+
       8 :              :        :      return i;
       9 :              :        :   char Buffer [100];
+
       9 :              :        :   end;
       10 :              :        :  
+
       10 :              :        :  
       11 :              :      1 :   printf ("1. Print string #1\n");
+
       11 :              :      2 :   procedure p1(I : in out integer) is
       12 :              :     1 :   printf ("2. Print string #2\n");
+
       12 :              :       :   begin
       13 :              :       :  
+
       13 :              :     2 :     if I = 0 then
+    14 :      2/2/1/2 :     2 :    while (Option < 1 || Option > 2)
+
          B      1x -> 16
                1 -> 16
+
      14 :              :      1 :       Text_Io.Put_Line("p1, 0!");
                0 -> 16
+
       15 :              :        :     else
       15 :              :        :   {
+
       16 :              :      1 :      Text_Io.Put_Line("p1, not zero");
       16 :              :      1 :      printf ("     Enter your choice (1 or 2): \n");
+
       17 :              :       :     end if;
       17 :              :     1 :       fgets (Buffer, 99, stdin);
+
       18 :              :      2 :   end p1;
       18 :              :      1 :       Option = atoi (Buffer);
+
       19 :              :        :  
       19 :              :        :   }
+
       20 :              :      2 :   procedure p2(I : in out float) is
       20 :              :        :     
+
       21 :              :        :   begin
+    21 :      2/2/1/0 :     1 :   switch (Option)
+
       22 :              :     2 :     if I < 0.000001 and then I > -0.000001 then
                1 -> 24
+
          B      1x -> 25
                0 -> 28
+
+        B      0x -> 25
       22 :              :        :   {
+
       23 :              :      1 :      Text_Io.Put_Line("p2, 0!");
       23 :              :       :    case 1:
+
      24 :              :        :    else
       24 :              :      1 :      printf ("This is string #1 - pretty exciting, huh?!\n");
+
       25 :              :      1 :      Text_Io.Put_Line("p2, not zero");
       25 :              :      1 :      break;
+
       26 :              :        :     end if;
       26 :              :        :  
+
       27 :              :     2 :   end p2;
       27 :              :       :    case 2:
+
      28 :              :       :  
*    28 :              :     0 :      printf ("This is string #2 - it doesn't get any better than this!\n");
+
       29 :              :       :  procedure td(i : in integer) is separate;
*    29 :              :     0 :       break;
+
       30 :              :        :  
       30 :              :        :   }
+
       31 :              :       : end pkg;
       31 :              :     1 : }
 
 
       32 :              :        :  
 
       32 :              :        :  
      33 :              :        : int main (int argc, char **argv)
 
      34 :              :      1 : {
 
      35 :              :      1 :    DoProcessing ();
 
      36 :              :      1 :    return 0;
 
      37 :              :      1 : }
 
  
O  - Number of offsets for line
 
B  - Number of branches for line
 
I  - Number of offsets/branches instrumented
 
I% - Percentage of offsets/branches instrumented
 
H  - Number of offsets/branches hit
 
H% - Percentage of offsets/branches hit
 
T  - Number of branches taken
 
N  - Number of branches not taken
 
+  - Partial coverage on this line
 
*  - No coverage on this line
 
 
</pre>
 
</pre>
 +
 +
You can use the <code>-q html</code> option with '''abrmerge''' to produce HTML reports which use colors to highlight the coverage status of lines and branches as well as other information in hover test.
  
 
=== Using abrmerge ===
 
=== Using abrmerge ===
Line 235: Line 317:
 
Sometimes we want to combine several test and branch coverage reports into a single report. Use [[AUG_Tools_Reference#abrmerge|abrmerge]] to accomplish this.
 
Sometimes we want to combine several test and branch coverage reports into a single report. Use [[AUG_Tools_Reference#abrmerge|abrmerge]] to accomplish this.
  
The above 2 lines that were not executed are specific to choice number 2. We could easily execute the lines of choice number 2 if we ran it again, but then we wouldn't be able to cover the choice 1 lines. If you look in the local directory, you'll see a coverage_example.tc file. This was created at format time by the coverage predefined probe and is a binary representation of the above data. It contains the coverage data obtained during choice 1, so let's save it.
+
The above 2 lines that were not executed are specific to choice number 2. We could easily execute the lines of choice number 2 if we ran it again, but then we wouldn't be able to cover the choice 1 lines. If you look in the local directory, you'll see <code>coverage_example.*.brc</code> files. These were created at format time by the '''brcov''' and '''coverage''' predefined probes. These contain the branch and line coverage data obtained during choice 1, so let's save it.
  
We typically use [[AUG_Tools_Reference#abrmerge|abrmerge]] to merge results from many .brc files (perhaps .brc files produced by coverage.ual and brcov.ual) and display the combined data, but it can also act on just one file. We need to save the current .brc file, and copying it would do, but we'll use abrmerge to demonstrate it a little:
+
We typically use [[AUG_Tools_Reference#abrmerge|abrmerge]] to merge results from many .brc files and display the combined data:
 
   
 
   
  abrmerge -m combined.brc brcov_example.brc
+
  abrmerge -m combined.brc coverage_example.*.brc  
 
 
This "merges" the data in the input .brc files (only brcov_example.brc) and outputs it in combined.brc (which, in this case, means that combined.brc ends up with the same data). You can verify that this combined.brc file has the same data by just running [[AUG_Tools_Reference#abrmerge|abrmerge]] on it:
 
  
abrmerge combined.brc
+
This "merges" the data in the input .brc files and outputs it in combined.brc.
  
 
Now run the application again using aprobe:
 
Now run the application again using aprobe:
  
  aprobe -u brcov brcov_example
+
  aprobe -u brcov -u coverage coverage_example
  
 
Select choice 2, then after the application ends re-run apformat:
 
Select choice 2, then after the application ends re-run apformat:
  
  apformat brcov_example
+
  apformat coverage_example
  
This time we get a different set of lines executed, as expected. Use the [[AUG_Tools_Reference#abrmerge|abrmerge]] command to combine the data in combined.brc (from the first run) with the data from this run (in a new brcov_example.brc):
+
This time we get a different set of lines executed, as expected. Use the [[AUG_Tools_Reference#abrmerge|abrmerge]] command to combine the data in combined.brc (from the first run) with the data from this run (in a new coverage_example.*.brc):
  
  abrmerge -m combined.brc brcov_example.brc combined.brc
+
  abrmerge -m combined.brc coverage_example.*.brc combined.brc
  
 
Now we get the 100% coverage we wanted!
 
Now we get the 100% coverage we wanted!
 
The on-line example in <code>$APROBE/examples/learn/branch_coverage</code> extends this by illustrating how to use your own probes in combination with coverage.ual to ensure all lines are executed.
 
  
 
=== Branch Coverage Report ===
 
=== Branch Coverage Report ===
  
The final output of the <code>learn/branch_coverage</code> example looks like this:
+
The branch coverage example report looks like this:
  
 
<pre>
 
<pre>
Line 269: Line 347:
  
  
Generated: 12 May 2017 13:36:25 -0400
+
Generated: 27 Nov 2017 09:19:05 -0500
 +
 
  
  
Line 283: Line 362:
 
Function Details
 
Function Details
 
File Coverage
 
File Coverage
 +
  
  
Line 290: Line 370:
  
 
TimeStamp:
 
TimeStamp:
Program  : /home/swn/aprobe/test/brcov/i2419e/brtestc.exe
+
Program  : /home/swn/aprobe/test/brcov/tnamec/main.exe
 
Host      : centos7
 
Host      : centos7
PID      : 18865
+
PID      : 13805
Start Time: 2017-05-11 17:41:53
+
Start Time: 2017-11-27 09:19:06
End Time  : 2017-05-11 17:57:58
+
End Time  : 2017-11-27 09:19:06
  
  
Line 306: Line 386:
 
Total    Total  Not    Not        Coverage  Total    Not      Not        Branches Not      Coverage
 
Total    Total  Not    Not        Coverage  Total    Not      Not        Branches Not      Coverage
 
Calls    Lines  Probed  Executed  Percent  Branches  Probed    Executed  Taken    Taken    Percent  Name
 
Calls    Lines  Probed  Executed  Percent  Branches  Probed    Executed  Taken    Taken    Percent  Name
------- ------- -------- --------- --------- --------- --------- ---------- --------- --------- -------- --------- - -
+
------- ------- -------- --------- ========= --------- --------- ---------- --------- --------- ======== --------- - -
    -1     -1       -1       -1        0        0        0          0        0        0       0  "crtstuff.c":"__do_global_dtors_aux()"
+
     2       5       0        0      100         1        0          0        1        1      100  extern:"pkg.p1[1]"
    -1      -1       -1        -1         0        0        0          0        0        0        0  "crtstuff.c":"deregister_tm_clones()"
+
    2      6       0        0      100        2        0          0        1         2      100  extern:"pkg.p2[1]"
    -1      -1      -1        -1         0        0         0          0        0        0        0  "crtstuff.c":"frame_dummy()"
+
    10     19       0        1        94        5         0          0        5         4     100  extern:"pkg.td[1]"
    -1      -1      -1        -1         0        0        0          0        0        0        0  "crtstuff.c":"register_tm_clones()"
 
381878      14        0         1       92        3        0          0        3        3     100  extern:"ExprFunc()"
 
381878    182       0       28        84        70         0         12        19        39       82  extern:"IfFunc()"
 
381878      27        0        5        81        5        0          0        3        5      100 extern:"LoopFunc()"
 
381878      21        0        1        95         2        0          0        2         2      100  extern:"LoopSwitchFunc()"
 
381878      5        0        1       80        0        0          0        0        0        0  extern:"StraightLineFunc()"
 
381878     17       0        1        94        1         0          0        1         1     100  extern:"SwitchFunc()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"__libc_csu_fini()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"__libc_csu_init()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"__x86.get_pc_thunk.bx()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"_fini()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"_init()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"_start()"
 
    -1      -1      -1        -1         0        0        0          0        0        0        0  extern:"ident()"
 
    -1      -1      -1        -1        0        0        0          0        0        0        0  extern:"main()"
 
  
 
Note: Negative counts indicate the function/line was not instrumented.
 
Note: Negative counts indicate the function/line was not instrumented.
Line 331: Line 396:
 
  Total    Not    Coverage    Total    Not      Not        Coverage  Total      Not        Not        Branches  Not        Coverage
 
  Total    Not    Coverage    Total    Not      Not        Coverage  Total      Not        Not        Branches  Not        Coverage
 
  Funcs    Called  Percent    Lines    Probed    Executed  Percent    Branches  Probed    Executed  Taken      Taken      Percent  
 
  Funcs    Called  Percent    Lines    Probed    Executed  Percent    Branches  Probed    Executed  Taken      Taken      Percent  
-------- -------- -------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
+
-------- -------- ======== ---------- ---------- ---------- ========== ---------- ---------- ---------- ---------- ---------- ==========
    18      12       33       266         0        37        86        81         0         12        28        50        85
+
       3       0      100        30         0         1         96          8          0         0         7          7        100
  
  
Line 340: Line 405:
 
--------------------------------------------------------------------------
 
--------------------------------------------------------------------------
  
"crtstuff.c":"__do_global_dtors_aux()" (<>)
+
extern:"pkg.p1[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
"crtstuff.c":"deregister_tm_clones()" (<>)
+
extern:"pkg.p2[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
"crtstuff.c":"frame_dummy()" (<>)
+
extern:"pkg.td[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)
"crtstuff.c":"register_tm_clones()" (<>)
 
extern:"ExprFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"IfFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"LoopFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"LoopSwitchFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"StraightLineFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"SwitchFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"__libc_csu_fini()" (<>)
 
extern:"__libc_csu_init()" (<>)
 
extern:"__x86.get_pc_thunk.bx()" (<>)
 
extern:"_fini()" (<>)
 
extern:"_init()" (<>)
 
extern:"_start()" (<>)
 
extern:"ident()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
extern:"main()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
  
  
 
--------------------------------------------------------------------------
 
--------------------------------------------------------------------------
Files TOC
+
File TOC
 
--------------------------------------------------------------------------
 
--------------------------------------------------------------------------
  
brtestc.c
+
pkg.ads
 +
pkg.adb
 +
pkg-td.adb
 +
main.adb
  
  
Line 372: Line 425:
  
  
"crtstuff.c":"__do_global_dtors_aux()" (<>)
+
extern:"pkg.p1[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
 
 
  
Calls:  -1
 
  
          Lines  Probed Not Probed  Hit
+
Calls: 2
        ------- -------- ---------- ----------
+
-----
Count:      -1        0        -1        0
 
Percent:                0        0        0
 
  
 +
Test Names: [ test p1 ]
 +
----------
  
          Branches    Probed      Hit      Taken    NotTaken
+
Lines:
        ---------- ---------- ---------- ---------- ----------
+
-----
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
"crtstuff.c":"deregister_tm_clones()" (<>)
 
 
 
 
 
Calls:  -1
 
 
 
 
           Lines  Probed  Not Probed  Hit  
 
           Lines  Probed  Not Probed  Hit  
 
         ------- -------- ---------- ----------
 
         ------- -------- ---------- ----------
Count:       -1         0       -1         0
+
Count:       5        5         0        5
Percent:               0        0         0
+
Percent:             100         0       100
  
  
 +
Branches:
 +
--------
 
           Branches    Probed      Hit      Taken    NotTaken
 
           Branches    Probed      Hit      Taken    NotTaken
 
         ---------- ---------- ---------- ---------- ----------
 
         ---------- ---------- ---------- ---------- ----------
Count:            0          0          0          0          0
+
Count:            1         1          1          1          1
Percent:                    0          0          0         0
 
 
 
 
 
"crtstuff.c":"frame_dummy()" (<>)
 
 
 
 
 
Calls:  -1
 
 
 
          Lines  Probed  Not Probed  Hit
 
         ------- -------- ---------- ----------
 
Count:      -1         0        -1        0
 
Percent:                0        0        0
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0         0
 
 
 
 
 
"crtstuff.c":"register_tm_clones()" (<>)
 
 
 
 
 
Calls:  -1
 
 
 
          Lines  Probed  Not Probed  Hit
 
         ------- -------- ---------- ----------
 
Count:      -1        0        -1         0
 
Percent:                0        0        0
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
extern:"ExprFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
 
 
 
 
Calls:  381878
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      14        14        0        13
 
Percent:              100        0        92
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            3          3          3          3          3
 
 
Percent:                  100        100        100        100
 
Percent:                  100        100        100        100
  
  
extern:"IfFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
+
extern:"pkg.p2[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
 
 
 
 
Calls:  381878
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      182      182        0      154
 
Percent:              100        0        84
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:          70        70        58        19        39
 
Percent:                  100        82        27        55
 
  
  
extern:"LoopFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
+
Calls: 2
 +
-----
  
 +
Test Names: [ test p1, test p2 ]
 +
----------
  
Calls: 381878
+
Lines:
 
+
-----
 
           Lines  Probed  Not Probed  Hit  
 
           Lines  Probed  Not Probed  Hit  
 
         ------- -------- ---------- ----------
 
         ------- -------- ---------- ----------
Count:       27       27         0       22
+
Count:        6        6         0         6
Percent:              100        0       81
+
Percent:              100        0       100
  
  
 +
Branches:
 +
--------
 
           Branches    Probed      Hit      Taken    NotTaken
 
           Branches    Probed      Hit      Taken    NotTaken
 
         ---------- ---------- ---------- ---------- ----------
 
         ---------- ---------- ---------- ---------- ----------
Count:            5         5         5         3         5
+
Count:            2         2         2         1         2
Percent:                  100        100        60       100
+
Percent:                  100        100        50       100
 
 
 
 
extern:"LoopSwitchFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
 
 
 
 
Calls:  381878
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      21        21        0        20
 
Percent:              100        0        95
 
 
 
  
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            2          2          2          2          2
 
Percent:                  100        100        100        100
 
  
 +
extern:"pkg.td[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)
  
extern:"StraightLineFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
  
 +
Calls:  10
 +
-----
  
Calls: 381878
+
Test Names: [ test p1, test p2 ]
 +
----------
  
 +
Lines:
 +
-----
 
           Lines  Probed  Not Probed  Hit  
 
           Lines  Probed  Not Probed  Hit  
 
         ------- -------- ---------- ----------
 
         ------- -------- ---------- ----------
Count:        5        5        0        4
+
Count:      19       19         0        18
Percent:              100        0        80
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
extern:"SwitchFunc()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
 
 
 
 
Calls:  381878
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      17       17         0        16
 
 
Percent:              100        0        94
 
Percent:              100        0        94
  
 +
    Lines Not Executed:
 +
    ------------------
 +
    21 / pkg-td.adb
  
 +
Branches:
 +
--------
 
           Branches    Probed      Hit      Taken    NotTaken
 
           Branches    Probed      Hit      Taken    NotTaken
 
         ---------- ---------- ---------- ---------- ----------
 
         ---------- ---------- ---------- ---------- ----------
Count:            1         1         1         1         1
+
Count:            5         5         5         5         4
Percent:                  100        100        100       100
+
Percent:                  100        100        100         80
  
  
extern:"__libc_csu_fini()" (<>)
 
  
 +
--------------------------------------------------------------------------
 +
Function Coverage Details
 +
--------------------------------------------------------------------------
  
Calls:  -1
 
  
          Lines  Probed  Not Probed  Hit
+
extern:"pkg.p1[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
        ------- -------- ---------- ----------
 
Count:       -1         0        -1        0
 
Percent:                0        0        0
 
  
 +
Lines:
 +
-----
 +
      Line    I    Count      File  [ Test Names ]
 +
    ---------- -  -----------  ---------------------
 +
            11 Y :          2 : pkg.adb [ test p1 ]
 +
            13 Y :          2 : pkg.adb [ test p1 ]
 +
            14 Y :          1 : pkg.adb [ test p1 ]
 +
            16 Y :          1 : pkg.adb [ test p1 ]
 +
            18 Y :          2 : pkg.adb [ test p1 ]
  
          Branches   Probed     Hit      Taken    NotTaken
+
Branches:
        ---------- ---------- ---------- ---------- ----------
+
--------
Count:           0          0         0         0         0
+
    Offset  I     Hit      Taken    NotTaken   Line/File -> Line/File  [ Test Names ]
Percent:                     0          0          0          0
+
    -------- -  ---------- ---------- ----------   --------------------------------------
 +
    0x00000b Y :          2         1         1 : 13 / pkg.adb -> 16 / pkg.adb [ test p1 ]
  
 +
Edges:
 +
------
 +
      Count    Offset/Line/File -> Offset/Line/File [ Test Names ]
 +
    ----------  ---------------------------------------------------
  
extern:"__libc_csu_init()" (<>)
+
extern:"pkg.p2[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
  
 +
Lines:
 +
-----
 +
      Line    I    Count      File  [ Test Names ]
 +
    ---------- -  -----------  ---------------------
 +
            20 Y :          2 : pkg.adb [ test p2 ]
 +
            22 Y :          2 : pkg.adb [ test p2 ]
 +
            22 Y :          1 : pkg.adb [ test p2 ]
 +
            23 Y :          1 : pkg.adb [ test p2 ]
 +
            25 Y :          1 : pkg.adb [ test p2 ]
 +
            27 Y :          2 : pkg.adb [ test p2 ]
  
Calls:  -1
+
Branches:
 +
--------
 +
    Offset  I      Hit      Taken    NotTaken    Line/File -> Line/File [ Test Names ]
 +
    -------- -  ---------- ---------- ----------  --------------------------------------
 +
    0x000013 Y :          2          1          1 : 22 / pkg.adb -> 25 / pkg.adb [ test p2 ]
 +
    0x000021 Y :          1          0          1 : 22 / pkg.adb -> 25 / pkg.adb [ test p2 ]
  
          Lines  Probed Not Probed  Hit
+
Edges:
        ------- -------- ---------- ----------
+
------
Count:      -1        0        -1        0
+
      Count    Offset/Line/File -> Offset/Line/File [ Test Names ]
Percent:                0        0        0
+
    ---------- ---------------------------------------------------
  
 +
extern:"pkg.td[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)
  
          Branches    Probed      Hit       Taken     NotTaken
+
Lines:
        ---------- ---------- ---------- ---------- ----------
+
-----
Count:           0          0         0         0         0
+
       Line    I     Count      File  [ Test Names ]
Percent:                     0         0         0         0
+
    ---------- - ----------- ---------------------
 +
            4 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            5 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            6 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            7 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            8 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            9 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            11 Y :        10 : pkg-td.adb [ test p1, test p2 ]
 +
            21 Y :         0 : pkg-td.adb [  ]
 +
            11 Y :          8 : pkg-td.adb [ test p1, test p2 ]
 +
            21 Y :          6 : pkg-td.adb [ test p2 ]
 +
            13 Y :          1 : pkg-td.adb [  ]
 +
            22 Y :         1 : pkg-td.adb [ test p1 ]
 +
            15 Y :         1 : pkg-td.adb [ test p1 ]
 +
            22 Y :         1 : pkg-td.adb [ test p1 ]
 +
            17 Y :         1 : pkg-td.adb [ test p1 ]
 +
            22 Y :          1 : pkg-td.adb [ test p2 ]
 +
            19 Y :         1 : pkg-td.adb [ test p2 ]
 +
            22 Y :         1 : pkg-td.adb [ test p2 ]
 +
            23 Y :        10 : pkg-td.adb [ test p1, test p2 ]
  
 +
Branches:
 +
--------
 +
    Offset  I      Hit      Taken    NotTaken    Line/File -> Line/File  [ Test Names ]
 +
    -------- -  ---------- ---------- ----------  --------------------------------------
 +
    0x000037 Y :        10          1          9 : 11 / pkg-td.adb -> 15 / pkg-td.adb [ test p2, test p1 ]
 +
    0x00003c Y :          9          8          1 : 11 / pkg-td.adb -> 11 / pkg-td.adb [ test p2, test p1 ]
 +
    0x000041 Y :          1          1          0 : 11 / pkg-td.adb -> 13 / pkg-td.adb [  ]
 +
    0x000048 Y :          8          1          7 : 11 / pkg-td.adb -> 17 / pkg-td.adb [ test p2, test p1 ]
 +
    0x00004d Y :          7          1          6 : 11 / pkg-td.adb -> 19 / pkg-td.adb [ test p2 ]
  
extern:"__x86.get_pc_thunk.bx()" (<>)
+
Edges:
 +
------
 +
      Count    Offset/Line/File -> Offset/Line/File [ Test Names ]
 +
    ----------  ---------------------------------------------------
  
  
Calls:  -1
+
--------------------------------------------------------------------------
 +
File Coverage
 +
--------------------------------------------------------------------------
  
          Lines  Probed  Not Probed  Hit
+
pkg.ads:
        ------- -------- ---------- ----------
 
Count:       -1        0        -1        0
 
Percent:                0        0        0
 
  
  
          Branches    Probed      Hit      Taken    NotTaken
+
+  - This line/branch/edge was not executed.
        ---------- ---------- ---------- ---------- ----------
+
- This internal branch/edge was not executed but may not be significant.
Count:            0          0          0          0          0
+
- This line/branch/edge was not probed.
Percent:                    0          0          0          0
 
  
 +
  Line    Edge/Branch  Line Cnt  Source
 +
  ------  -----------  ---------  ------- - -
 +
      1 :              :        :
 +
      2 :              :        : package pkg is
 +
      3 :              :        :
 +
      4 :              :        :  procedure p1(I : in out integer);
 +
      5 :              :        :  procedure p2(I : in out float);
 +
      6 :              :        :
 +
      7 :              :        :  procedure td(I : in integer);
 +
      8 :              :        :
 +
      9 :              :        : end pkg;
 +
      10 :              :        :
  
extern:"_fini()" (<>)
+
pkg.adb:
  
  
Calls: -1
+
+ - This line/branch/edge was not executed.
 +
.  - This internal branch/edge was not executed but may not be significant.
 +
*  - This line/branch/edge was not probed.
  
          Lines   Probed  Not Probed   Hit
+
  Line    Edge/Branch   Line Cnt   Source
        ------- -------- ---------- ----------
+
  ------   -----------   --------- ------- - -
Count:      -1         0        -1         0
+
      1 :              :        :
Percent:               0         0        0
+
      2 :              :        : with Text_Io;
 +
      3 :              :        :
 +
      4 :              :        : package body pkg is
 +
      5 :              :        :
 +
      6 :              :        :  function Ident(i : integer) return integer is
 +
      7 :              :        :  begin
 +
      8 :              :        :      return i;
 +
      9 :              :        :  end;
 +
      10 :              :        :
 +
      11 :              :      2 :  procedure p1(I : in out integer) is
 +
       12 :              :        :  begin
 +
      13 :              :      2 :    if I = 0 then
 +
          B      1x -> 16
 +
      14 :              :      1 :      Text_Io.Put_Line("p1, 0!");
 +
      15 :              :       :    else
 +
      16 :              :      1 :      Text_Io.Put_Line("p1, not zero");
 +
      17 :              :        :    end if;
 +
      18 :              :      2 :  end p1;
 +
      19 :              :        :
 +
      20 :              :      2 :  procedure p2(I : in out float) is
 +
      21 :              :        :  begin
 +
      22 :              :      2 :     if I < 0.000001 and then I > -0.000001 then
 +
          B      1x -> 25
 +
+         B      0x -> 25
 +
      23 :              :      1 :      Text_Io.Put_Line("p2, 0!");
 +
      24 :              :        :    else
 +
      25 :              :      1 :      Text_Io.Put_Line("p2, not zero");
 +
      26 :              :        :    end if;
 +
      27 :              :      2 :  end p2;
 +
      28 :              :        :
 +
      29 :              :        :  procedure td(i : in integer) is separate;
 +
      30 :              :        :
 +
      31 :              :        : end pkg;
 +
      32 :              :        :
  
 +
pkg-td.adb:
  
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
  
 +
+  - This line/branch/edge was not executed.
 +
.  - This internal branch/edge was not executed but may not be significant.
 +
*  - This line/branch/edge was not probed.
  
extern:"_init()" (<>)
+
  Line    Edge/Branch  Line Cnt  Source
 +
  ------  -----------  ---------  ------- - -
 +
      1 :             :        :
 +
      2 :              :        : separate(pkg)
 +
      3 :              :        :
 +
      4 :              :    10 : procedure td(i : in integer) is
 +
      5 :              :    10 :  i0 : integer := 0;
 +
      6 :              :    10 :  i1 : integer := 1;
 +
      7 :              :    10 :  f0 : float := 0.0;
 +
      8 :              :    10 :  f1 : float := 1.0;
 +
      9 :              :    10 :  l  : integer := 0;
 +
      10 :              :        : begin
 +
      11 :              :    10 :  case i is
 +
          B      1x -> 15
 +
          B      1x -> 13
 +
          B      1x -> 17
 +
          B      1x -> 19
 +
      12 :              :        :  when 1 =>
 +
      13 :              :      1 :    p1(i0);
 +
      14 :              :        :  when 2 =>
 +
      15 :              :      1 :    p1(i1);
 +
      16 :              :        :  when 3 =>
 +
      17 :              :      1 :    p2(f0);
 +
      18 :              :        :  when 4 =>
 +
      19 :              :      1 :    p2(f1);
 +
      20 :              :        :  when others =>
 +
      21 :              :      6 :    null;
 +
      22 :              :      1 :  end case;
 +
      23 :              :    10 : end td;
 +
      24 :              :        : 
  
 +
main.adb:
  
Calls:  -1
 
  
          Lines  Probed Not Probed  Hit
+
+ - This line/branch/edge was not executed.
        ------- -------- ---------- ----------
+
- This internal branch/edge was not executed but may not be significant.
Count:      -1        0        -1        0
+
- This line/branch/edge was not probed.
Percent:                0        0        0
 
  
 +
  Line    Edge/Branch  Line Cnt  Source
 +
  ------  -----------  ---------  ------- - -
 +
      1 :              :        :
 +
      2 :              :        : with Text_Io;
 +
      3 :              :        : with pkg;
 +
      4 :              :        :
 +
      5 :              :        : procedure Main is
 +
      6 :              :        : begin
 +
      7 :              :        :    for i in 1..10 loop
 +
      8 :              :        :      pkg.td(i);
 +
      9 :              :        :    end loop;
 +
      10 :              :        : end Main;
 +
      11 :              :        :
  
          Branches    Probed      Hit      Taken    NotTaken
+
</pre>
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
extern:"_start()" (<>)
 
 
 
 
 
Calls:  -1
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      -1        0        -1        0
 
Percent:                0        0        0
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
extern:"ident()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
 
 
 
 
Calls:  -1
 
  
          Lines  Probed  Not Probed  Hit
+
==== Example D-3. Branch Coverage Summary Report ====
        ------- -------- ---------- ----------
 
Count:      -1        0        -1        0
 
Percent:                0        0        0
 
  
 +
There is more information about interpreting the Branch Coverage Reports in [[Branch_Coverage_Cheat_Sheet]].
  
          Branches    Probed      Hit      Taken    NotTaken
+
Here is and example of the HTML branch coverage report:
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
extern:"main()" (/home/swn/aprobe/test/brcov/i2419e/brtestc.c)
 
 
 
 
 
Calls:  -1
 
 
 
          Lines  Probed  Not Probed  Hit
 
        ------- -------- ---------- ----------
 
Count:      -1        0        -1        0
 
Percent:                0        0        0
 
 
 
 
 
          Branches    Probed      Hit      Taken    NotTaken
 
        ---------- ---------- ---------- ---------- ----------
 
Count:            0          0          0          0          0
 
Percent:                    0          0          0          0
 
 
 
 
 
 
 
--------------------------------------------------------------------------
 
File Coverage
 
--------------------------------------------------------------------------
 
 
 
brtestc.c:
 
 
 
          Line  Branch
 
  Line  Count  Count    Source
 
  ------ ------- -------  ------ - -
 
      1                :
 
      2                : #include <stdlib.h>
 
      3                :
 
      4                : int ident(int i)
 
      5                : {
 
      6                :    return i;
 
      7                : }
 
      8                :
 
      9                : int StraightLineFunc(int i)
 
      10  381878      0 : {
 
      11  381878      0 :    int result = 0;
 
      12                :
 
      13  381878      0 :    result = result + i;
 
      14  381878      0 :    return result;
 
*    15      0      0 : }
 
      16                :
 
      17                : int LoopFunc(int i)
 
      18  381878      0 : {
 
      19  381878      0 :    int j = 0;
 
      20  381878      0 :    int k = 0;
 
      21                :
 
      22                :    /* no iterations */
 
+    23  381878      1 :    for (j = 0; j < 0; j++)
 
        0 -> 25
 
      24                :    {
 
*    25      0      0 :      k = k + i;
 
      26                :    }
 
      27                :
 
      28 4200658      1 :    for (j = 0; j < 10; j++)
 
  3818780 -> 30
 
      29                :    {
 
      30 3818780      0 :      k = k + i;
 
      31                :    }
 
      32                :     
 
      33  381878      0 :    j = 0;
 
+    34  381878      1 :    while (j < 0)
 
        0 -> 36
 
      35                :    {
 
*    36      0      0 :      k = k + 2;
 
*    37      0      0 :      j = j + 1;
 
      38                :    }
 
      39                :   
 
      40  381878      0 :    j = 0;
 
      41 4200658      1 :    while (j < 10)
 
  3818780 -> 43
 
      42                :    {
 
      43 3818780      0 :      k = k + 2;
 
      44 3818780      0 :      j = j + 1;
 
      45                :    }
 
      46                :   
 
      47  381878      0 :    j = 0;
 
      48                :    do
 
      49                :    {
 
      50 3818780      0 :      k = k + 2;
 
      51 3818780      0 :      j = j + 1;
 
      52                :    }
 
      53 3818780      1 :    while (j < 10);
 
  3436902 -> 50
 
      54                :   
 
      55  381878      0 :    return k;
 
*    56      0      0 : }
 
      57                :
 
      58                :
 
      59                : int ExprFunc(int i)
 
      60  381878      0 : {
 
      61  381878      0 :    int k = 0;
 
      62                :
 
      63  381878      1 :    k = (i > 2 ? 5 : 1);
 
        3 -> 63
 
      64                :
 
      65  381878      2 :    k = (i > 5 ? (i < 10 ? 5 : 1) : 7);
 
        6 -> 65
 
  381867 -> 65
 
      66                :
 
      67  381877      0 :    return k;
 
*    68      0      0 : }
 
      69                :
 
      70                :
 
      71                : int SwitchFunc(int i)
 
      72  381878      0 : {
 
      73  381878      0 :    int k = 0;
 
      74                :
 
      75  381878      1 :    switch (i)
 
  381872 -> 95
 
      76                :    {
 
      77                :    case 0:
 
      78      1      0 :      k = k + 1;
 
      79      1      0 :      break;
 
      80                :    case 1:
 
      81      1      0 :      k = k + 1;
 
      82      1      0 :      break;
 
      83                :    case 2:
 
      84      1      0 :      k = k + 2;
 
      85                :    case 3:
 
      86      2      0 :      k = k + 3;
 
      87      2      0 :      break;
 
      88                :    case 4:
 
      89      1      0 :      k = k + 4;
 
      90      1      0 :      break;
 
      91                :    case 5:
 
      92      1      0 :      k = k + 5;
 
      93      1      0 :      break;
 
      94                :    default:
 
      95  381872      0 :      k = k + 6;
 
      96                :    }
 
      97                :
 
      98  381878      0 :    return k;
 
*    99      0      0 : }
 
    100                :
 
    101                :
 
    102                : int LoopSwitchFunc(int i)
 
    103  381878      0 : {
 
    104  381878      0 :    int k = 0;
 
    105  381878      0 :    int j = 0;
 
    106                :   
 
    107 4200658      1 :    for (j = 0; j < 10; j++)
 
  3818780 -> 109
 
    108                :    {
 
    109 3818780      1 :      switch (i)
 
  3818720 -> 129
 
    110                :      {
 
    111                :      case 0:
 
    112      10      0 :          k = k + 1;
 
    113      10      0 :          break;
 
    114                :      case 1:
 
    115      10      0 :          k = k + 1;
 
    116      10      0 :          break;
 
    117                :      case 2:
 
    118      10      0 :          k = k + 2;
 
    119                :      case 3:
 
    120      20      0 :          k = k + 3;
 
    121      20      0 :          break;
 
    122                :      case 4:
 
    123      10      0 :          k = k + 4;
 
    124      10      0 :          break;
 
    125                :      case 5:
 
    126      10      0 :          k = k + 5;
 
    127      10      0 :          break;
 
    128                :      default:
 
    129 3818720      0 :          k = k + 6;
 
    130                :      }
 
    131                :    }
 
    132                :
 
    133  381878      0 :    return k;
 
*    134      0      0 : }
 
    135                :
 
    136                : int IfFunc(int i)
 
    137  381878      0 : {
 
    138  381878      0 :    int j = 0;
 
    139  381878      0 :    int k = 0;
 
    140                :
 
    141                :    /* never taken */
 
+    142  381878      1 :    if (ident(j) < 0)
 
  381878 -> 147
 
    143                :    {
 
*    144      0      0 :      j = j + 1;
 
    145                :    }
 
    146                :
 
+    147  381878      1 :    if (ident(j) < 1000)
 
        0 -> 153
 
    148                :    {
 
    149  381878      0 :      j = j + 1;
 
    150                :    }
 
    151                :
 
    152                :    /* else taken */
 
+    153  381878      1 :    if (ident(j) < 0)
 
  381878 -> 159
 
    154                :    {
 
*    155      0      0 :      j = j + 1;
 
    156                :    }
 
    157                :    else
 
    158                :    {
 
    159  381878      0 :      j = j + 2;
 
    160                :    }
 
    161                :
 
    162                :    /* second branch */
 
+    163  381878      1 :    if (ident(j) < 0)
 
  381878 -> 167
 
    164                :    {
 
*    165      0      0 :      j = j + 1;
 
    166                :    }
 
+    167  381878      1 :    else if (ident(j) < 5)
 
        0 -> 173
 
    168                :    {
 
    169  381878      0 :      j = j + 2;
 
    170                :    }
 
    171                :    else
 
    172                :   {
 
*    173      0      0 :      j = j + 2;
 
    174                :    }
 
    175                :
 
    176                :    /* multiple conditions */
 
    177                :
 
+    178  381878      1 :    if ((ident(k) < 0) | (ident(j) >= 0))
 
        0 -> 183
 
    179                :    {
 
    180  381878      0 :      j = j + 1;
 
    181                :    }
 
    182                :
 
+    183  381878      1 :    if ((ident(j) >= 0) | (ident(k) == 0))
 
        0 -> 189
 
    184                :    {
 
    185  381878      0 :      j = j + 1;
 
    186                :    }
 
    187                :
 
    188                :    /* all false */
 
+    189  381878      1 :    if ((ident(j) >= 1111110) |
 
  381878 -> 198
 
    190  381878      0 :        (1111110 == ident(k)) |
 
    191  381878      0 :        (ident(k) == 1111110) |
 
    192  381878      0 :        (111110 <= ident(j)))
 
    193                :    {
 
*    194      0      0 :      j = j + 1;
 
    195                :    }
 
    196                :
 
    197                :    /* fourth true */
 
+    198  381878      1 :    if ((ident(j) >= 1111110) |
 
        0 -> 207
 
    199  381878      0 :        (1111110 == ident(k)) |
 
    200  381878      0 :        (ident(k) == 1111110) |
 
    201  381878      0 :        (0 <= ident(j)))
 
    202                :    {
 
    203  381878      0 :      j = j + 1;
 
    204                :    }
 
    205                :
 
    206                :    /* third true */
 
+    207  381878      1 :    if ((ident(j) >= 1111110) |
 
        0 -> 216
 
    208  381878      0 :        (1111110 == ident(k)) |
 
    209  381878      0 :        (ident(k) == 0) |
 
    210  381878      0 :        (111110 <= ident(j)))
 
    211                :    {
 
    212  381878      0 :      j = j + 1;
 
    213                :    }
 
    214                :
 
    215                :    /* second true */
 
+    216  381878      1 :    if ((ident(j) >= 1111110) |
 
        0 -> 225
 
    217  381878      0 :        (0 == ident(k)) |
 
    218  381878      0 :        (ident(k) == 1111110) |
 
    219  381878      0 :        (111110 <= ident(j)))
 
    220                :    {
 
    221  381878      0 :      j = j + 1;
 
    222                :    }
 
    223                :
 
    224                :    /* first true */
 
+    225  381878      1 :    if ((ident(j) >= 0) |
 
        0 -> 233
 
    226  381878      0 :        (1111110 == ident(k)) |
 
    227  381878      0 :        (ident(k) == 1111110) |
 
    228  381878      0 :        (111110 <= ident(j)))
 
    229                :    {
 
    230  381878      0 :      j = j + 1;
 
    231                :    }
 
    232                :
 
+    233  381878      1 :    if ((ident(j) < 0) & (ident(k) == 0))
 
  381878 -> 238
 
    234                :    {
 
*    235      0      0 :      j = j + 1;
 
    236                :    }
 
    237                :
 
+    238  381878      1 :    if ((ident(j) >= 0) & (ident(k) != 0))
 
  381878 -> 243
 
    239                :    {
 
*    240      0      0 :      j = j + 1;
 
    241                :    }
 
    242                :
 
+    243  381878      1 :    if ((ident(j) >= 0) & (ident(k) == 0))
 
        0 -> 249
 
    244                :    {
 
    245  381878      0 :      j = j + 1;
 
    246                :    }
 
    247                :
 
    248                :    /* all true */
 
+    249  381878      1 :    if ((ident(j) >= 0) &
 
        0 -> 258
 
    250  381878      0 :        (ident(k) == 0) &
 
    251  381878      0 :        (0 == ident(k)) &
 
    252  381878      0 :        (0 <= ident(j)))
 
    253                :    {
 
    254  381878      0 :      j = j + 1;
 
    255                :    }
 
    256                :
 
    257                :    /* fourth false */
 
+    258  381878      1 :    if ((ident(j) >= 0) &
 
  381878 -> 267
 
    259  381878      0 :        (ident(ident(k)) == 0) &
 
    260  381878      0 :        (0 == ident(ident(k))) &
 
    261  381878      0 :        (10000 <= ident(j)))
 
    262                :    {
 
*    263      0      0 :      j = j + 1;
 
    264                :    }
 
    265                :
 
    266                :    /* third false */
 
+    267  381878      1 :    if ((ident(j) >= 0) &
 
  381878 -> 276
 
    268  381878      0 :        (ident(ident(k)) == 0) &
 
    269  381878      0 :        (5555 == ident(ident(k))) &
 
    270  381878      0 :        (0 <= ident(j)))
 
    271                :    {
 
*    272      0      0 :      j = j + 1;
 
    273                :    }
 
    274                :
 
    275                :    /* second false */
 
+    276  381878      1 :    if ((ident(j) >= 0) &
 
        0 -> 285
 
    277  381878      0 :        (ident(ident(k)) == 0) &
 
    278  381878      0 :        (0 == ident(ident(k))) &
 
    279  381878      0 :        (0 <= ident(j)))
 
    280                :    {
 
    281  381878      0 :      j = j + 1;
 
    282                :    }
 
    283                :
 
    284                :    /* first false */
 
+    285  381878      1 :    if ((ident(j) >= 10000) &
 
  381878 -> 295
 
    286  381878      0 :        (ident(ident(k)) == 0) &
 
    287  381878      0 :        (0 == ident(ident(k))) &
 
    288  381878      0 :        (0 <= ident(j)))
 
    289                :    {
 
*    290      0      0 :      j = j + 1;
 
    291                :    }
 
    292                :
 
    293                :    /* short circuits */
 
    294                :
 
+    295  381878      2 :    if ((ident(k) < 0) || (ident(j) >= 0))
 
        0 -> 297
 
        0 -> 300
 
    296                :    {
 
    297  381878      0 :      j = j + 1;
 
    298                :    }
 
    299                :
 
+    300  381878      1 :    if ((ident(j) >= 0) || (ident(k) == 0))
 
  381878 -> 302
 
        0 -> 306
 
    301                :    {
 
    302  381878      0 :      j = j + 1;
 
    303                :    }
 
    304                :
 
    305                :    /* all false */
 
+    306  381878      1 :    if ((ident(j) >= 1111110) ||
 
        0 -> 311
 
+    307  381878      1 :        (1111110 == ident(k)) ||
 
        0 -> 311
 
+    308  381878      1 :        (ident(k) == 1111110) ||
 
        0 -> 311
 
+    309  381878      1 :        (111110 <= ident(j)))
 
  381878 -> 315
 
    310                :    {
 
*    311      0      0 :      j = j + 1;
 
    312                :    }
 
    313                :
 
    314                :    /* fourth true */
 
+    315  381878      1 :    if ((ident(j) >= 1111110) ||
 
        0 -> 320
 
+    316  381878      1 :        (1111110 == ident(k)) ||
 
        0 -> 320
 
+    317  381878      1 :        (ident(k) == 1111110) ||
 
        0 -> 320
 
+    318  381878      1 :        (0 <= ident(j)))
 
        0 -> 324
 
    319                :    {
 
    320  381878      0 :      j = j + 1;
 
    321                :    }
 
    322                :
 
    323                :    /* third true */
 
+    324  381878      1 :    if ((ident(j) >= 1111110) ||
 
        0 -> 329
 
+    325  381878      1 :        (1111110 == ident(k)) ||
 
        0 -> 329
 
+    326  381878      1 :        (ident(k) == 0) ||
 
  381878 -> 329
 
*    327      0      0 :        (111110 <= ident(j)))
 
        0 -> 333
 
    328                :    {
 
    329  381878      0 :      j = j + 1;
 
    330                :    }
 
    331                :
 
    332                :    /* second true */
 
+    333  381878      1 :    if ((ident(j) >= 1111110) ||
 
        0 -> 338
 
+    334  381878      1 :        (0 == ident(k)) ||
 
  381878 -> 338
 
*    335      0      0 :        (ident(k) == 1111110) ||
 
        0 -> 338
 
*    336      0      0 :        (111110 <= ident(j)))
 
        0 -> 342
 
    337                :    {
 
    338  381878      0 :      j = j + 1;
 
    339                :    }
 
    340                :
 
    341                :    /* first true */
 
+    342  381878      1 :    if ((ident(j) >= 0) ||
 
  381878 -> 347
 
*    343      0      0 :        (1111110 == ident(k)) ||
 
        0 -> 347
 
*    344      0      0 :        (ident(k) == 1111110) ||
 
        0 -> 347
 
*    345      0      0 :        (111110 <= ident(j)))
 
        0 -> 350
 
    346                :    {
 
    347  381878      0 :      j = j + 1;
 
    348                :    }
 
    349                :
 
+    350  381878      1 :    if ((j < 0) && (ident(k) == 0))
 
  381878 -> 355
 
        0 -> 355
 
    351                :    {
 
*    352      0      0 :      j = j + 1;
 
    353                :    }
 
    354                :
 
+    355  381878      2 :    if ((j >= 0) && (ident(k) != 0))
 
        0 -> 360
 
  381878 -> 360
 
    356                :    {
 
*    357      0      0 :      j = j + 1;
 
    358                :    }
 
    359                :
 
+    360  381878      2 :    if ((j >= 0) && (ident(k) == 0))
 
        0 -> 366
 
        0 -> 366
 
    361                :    {
 
    362  381878      0 :      j = j + 1;
 
    363                :    }
 
    364                :
 
    365                :    /* all true */
 
+    366  381878      1 :    if ((ident(j) >= 0) &&
 
        0 -> 375
 
+    367  381878      1 :        (ident(k) == 0) &&
 
        0 -> 375
 
+    368  381878      1 :        (0 == ident(k)) &&
 
        0 -> 375
 
+    369  381878      1 :        (0 <= ident(j)))
 
        0 -> 375
 
    370                :    {
 
    371  381878      0 :      j = j + 1;
 
    372                :    }
 
    373                :
 
    374                :    /* fourth false */
 
+    375  381878      1 :    if ((ident(j) >= 0) &&
 
        0 -> 384
 
+    376  381878      1 :        (ident(k) == 0) &&
 
        0 -> 384
 
+    377  381878      1 :        (0 == ident(k)) &&
 
        0 -> 384
 
+    378  381878      1 :        (10000 <= ident(j)))
 
  381878 -> 384
 
    379                :    {
 
*    380      0      0 :      j = j + 1;
 
    381                :    }
 
    382                :
 
    383                :    /* third false */
 
+    384  381878      1 :    if ((ident(j) >= 0) &&
 
        0 -> 393
 
+    385  381878      1 :        (ident(k) == 0) &&
 
        0 -> 393
 
+    386  381878      1 :        (5555 == ident(k)) &&
 
  381878 -> 393
 
*    387      0      0 :        (0 <= ident(j)))
 
        0 -> 393
 
    388                :    {
 
*    389      0      0 :      j = j + 1;
 
    390                :    }
 
    391                :
 
    392                :    /* second false */
 
+    393  381878      1 :    if ((ident(j) >= 0) &&
 
        0 -> 402
 
+    394  381878      1 :        (ident(k) == 0) &&
 
        0 -> 402
 
+    395  381878      1 :        (0 == ident(k)) &&
 
        0 -> 402
 
+    396  381878      1 :        (0 <= ident(j)))
 
        0 -> 402
 
    397                :    {
 
    398  381878      0 :      j = j + 1;
 
    399                :    }
 
    400                :
 
    401                :    /* first false */
 
+    402  381878      1 :    if ((ident(j) >= 10000) &&
 
  381878 -> 410
 
*    403      0      0 :        (ident(k) == 0) &&
 
        0 -> 410
 
*    404      0      0 :        (0 == ident(k)) &&
 
        0 -> 410
 
*    405      0      0 :        (0 <= ident(j)))
 
        0 -> 410
 
    406                :    {
 
*    407      0      0 :      j = j + 1;
 
    408                :    }
 
    409                :
 
    410  381878      0 :    return j;
 
    411  381878      0 : }
 
    412                :
 
    413                : int main(int argc, char **argv)
 
    414                : {
 
    415                :    int i;
 
    416                :
 
    417                :    int loop_count = 10;
 
    418                :
 
    419                :    if (argc > 1)  loop_count = atoi(argv[1]);
 
    420                :
 
    421                :    for (i = 0; i < loop_count; i++)
 
    422                :    {
 
    423                :      StraightLineFunc(i);
 
    424                :      LoopFunc(i);
 
    425                :      SwitchFunc(i);
 
    426                :      LoopSwitchFunc(i);
 
    427                :      IfFunc(i);
 
    428                :      ExprFunc(i);
 
    429                :    }
 
    430                :
 
    431                :    return i;
 
    432                : }
 
    433                :
 
    434                :
 
 
 
O  - Number of offsets for line
 
B  - Number of branches for line
 
I  - Number of offsets/branches instrumented
 
I% - Percentage of offsets/branches instrumented
 
H  - Number of offsets/branches hit
 
H% - Percentage of offsets/branches hit
 
T  - Number of branches taken
 
N  - Number of branches not taken
 
+  - Partial coverage on this line
 
*  - No coverage on this line
 
</pre>
 
  
==== Example D-3. Test Coverage Summary Report ====
+
[[File:Brcov example HTML.jpeg|1200px]]
  
 
[[Category:UAL]]
 
[[Category:UAL]]
 
[[Category:Predefined Probe]]
 
[[Category:Predefined Probe]]
 
[[Category:Coverage]]
 
[[Category:Coverage]]

Latest revision as of 06:24, 20 March 2018

Branch Coverage Predefined Probe: brcov.ual

NOTE: This predefined probe was developed as a prototype. As of Aprobe version 4.4.9 the branch coverage features are available in the coverage.ual predefined probe. See coverage.ual for more information.

NOTE: This description is current for Aprobe version 4.4.8, 8 January 2018. The current version of this probe should be run with the coverage.ual to provide the line and function coverage information. Furthermore, coverage.ual should be configured to select the same functions as brcov.ual and should use the ProduceBrcovOutput option to produce compatible data to merge with brcov.ual. Eventually, brcov.ual will be a stand-alone probe.

The brcov.ual predefined probe supports branch coverage analysis on user applications. Branch coverage tells you exactly which branches within a function were actually hit during program execution. This allows you to develop unit test cases which can be used to confirm that all the branches of code you have written are executed and taken.

While this probe is a unique and powerful tool for collecting branch coverage information, it is only a tool. Getting complete branch coverage on a function can be a difficult task, and requires the user to compose test cases which will cause all paths to be executed, including error conditions and exception propagation. The brcov.ual probe can be used with the coverage.ual to produce comprehensive test coverage information.

But it should be noted that it is in testing these tricky cases that Aprobe can especially useful, since you as a user can write a probe that modifies the data on_entry to a function to force a specific path through the function, without worrying about how to get the normal caller of that function to pass that erroneous data.

Below is an example that works through some of the issues that arise from using Aprobe to do this. It is based on the coverage.ual example in the $APROBE/examples/learn/coverage directory. Additionally you are encouraged to contact OC Systems to discuss using Aprobe on your specific application.

Usage

This probe is applied at run time using aprobe as described under Branch Coverage UAL Parameters below. The only functions for which data will be collected are functions selected in the configuration file (see Branch Coverage Configuration File). Selecting a function means that branches in the function will be instrumented. Conversely, branches in functions that are not selected will not be instrumented, and no record will be kept of invocations of these functions or branches.

The instrumentation of branches requires that there be accurate source line debugging information recorded in the executable. This generally means that the application or library containing the covered functions:

  • must have been compiled with the appropriate debug flag (-g);
  • should have been compiled without optimization; and
  • must have the debug information still available.

A snapshot of the current state of collected branch coverage data may be written to the APD file while the program is running (see Configuration of Snapshots). Taking such periodic snapshots at known events, like the entry to or exit from a particular function, may help correlate state data with the execution path recorded by the brcov probe. A final snapshot occurs automatically at program termination.

After the application program terminates, the apformat command must be run to produce an XML branch coverage .brc file from the collected data. Use the abrmerge tool to produce reports and from the .brc files. Data from multiple runs may be merged into a single .brc file and a single report using abrmerge (see abrcmerge below). Coverage data from brcov.ual and coverage.ual can be combined using Abrmerge to produce very extensive reports.

The report produced by the abrcmerge consists of several parts: the "Overall Summary," the "Subprogram Summary," the "Subprogram Details," and the "Source Annotation." (A subprogram is another name for a function, procedure, subroutine -- any callable entity.) The summaries list the total lines and branches in the subprogram, how many lines/branches were not instrumented nor executed, and the percentage of instrumented lines/branches that were executed for the subprogram. The details section reports whether the subprogram was called, and if it was, it will report how many of the instrumented lines/branches were executed. In cases where coverage is less than 100% for a particular subprogram, the details section will also list instrumented lines/branches which were not executed. The source section will annotate any provided source files with branch/line coverage information which will assist with test case creation. Some parts of the report are options. The branch coverage report will look similar to that in Branch Coverage Summary Report.

Branch Coverage UAL Parameters

brcov.ual is specified on the aprobe command line or in an APO file, and with apformat. The specific options are:

aprobe   -u brcov[.ual]    [-p " [-c config_filename] [-o data_filename] [-f name_len] [-h] [-v]"   your_program 

For example:

aprobe -u brcov -p "-c foo1.brcov.cfg" foo.exe
aprobe -u brcov -p 

where:

-c config_filename

specifies that the name of the probe configuration options file will follow immediately after -c. The default file name is your_program.brcov.cfg. For example, if your executable program is called wilbur.exe, then the default file name would be wilbur.exe.brcov.cfg.
-f name_len

truncates function names to the specified length.
-h
produces brief help text.
-o data_filename

specifies the name for the branch coverage data file created during execution. The default file name is your_program.brc. For example, if your executable program is called wilbur.exe, then the default file name would be wilbur.exe.brc.
-v
verbose mode, which produces additional progress messages.

Note that if you use no UAL parameters, you need not specify UAL names to apformat. For example:

apformat progname

will format progname.apd with all the UALs with which it was created.

Branch Coverage Configuration File

The Branch Coverage configuration file is used to specify what subprograms are to be analyzed, when snapshots are to be taken, and other options, as described in Configuration File. The example below shows one possible Branch Coverage configuration file.

PROBE CONFIGURATION FILE FOR BRCOV VERSION 1.0.0

CoverageEnabledInitially TRUE

// Here we select which subprograms we want to cover:
COVERAGE "main"
COVERAGE extern:"YET_ANOTHER_LOCAL_PROC"
COVERAGE "STILL_ANOTHER_LOCAL_PROC"

// Here we define which subprogram invocations cause snapshots
// to be saved.
SNAPSHOT "printf" IN "libc.a(shr.o)" ON ENTRY IS "printf called"

Example D-2. brcov.cfg File

Note that if you do not provide a configuration file, the probe will create a default configuration file for you. This is a good way to get started.

Configuration Variables

The following are the only valid keywords that identify lines to set configuration variables. Each such line must begin with one of these keywords, and the keyword must be followed by a value. Nothing else is allowed on the same line.

CoverageEnabledInitially

This must be followed by the value TRUE or FALSE. The default is TRUE which indicates that data logging will begin as soon as the application program starts running. If set to FALSE, data logging will begin only after a call is made to the probe's function ap_Brcov_Enable(), rather than as soon as the application program starts running.

ShowAllSnapshots

This must be followed by TRUE or FALSE. The default is FALSE. When FALSE, the data from all intermediate snapshots are rolled into the one final report. When TRUE the data for every snapshot will be reported in separate summaries.

ResetSnapshotCounts

This must be followed by TRUE or FALSE. The default is FALSE. When FALSE, the data from all intermediate snapshots accumulate into the one final report. When TRUE the counts are reset for each separate snapshot.

ShowUnconditionalBranches

This must be followed by TRUE or FALSE. The default is FALSE, which indicates that unconditional branches will not be tracked. In general, conditional branches are more interesting than unconditional branches.

Configuration of Branch Coverage Functions

Each function for which branch coverage data is to be collected must be specified explicitly using the COVERAGE, COVERFILE, or COVERUNIT keywords.

The COVERAGE keyword is followed by the name of the function, as described in Configuration of Selected Functions. This directive selects specific functions by name (with possible wildcards).

The COVERFILE keyword is followed by the name of a file and an option module name. This keyword selects the functions originating from the designated source file (with possible wildcards).

The COVERUNIT keyword is followed by the name of a PowerAda unit. This keyword selects the functions originating from the designated PowerAda unit (with possible wildcards).

By default, if no COVERAGE/COVERFILE/COVERUNIT lines exist, then coverage data will only be collected for the "main()" function of the application module.

The REMOVE keyword allows you to specify subprograms that should not be instrumented for logging coverage data. This is useful when used in conjunction with a wildcard ("*"), to gather data about everything except certain routines.

Note: COVERAGE "*" is not a particuarly useful concept since it is important for you to identify and isolate your functions carefully in order to use test coverage for its intended purpose.

Configuration of Snapshots

The branch coverage probe configuration file allows you to specify the name of some subprograms for which snapshots of the coverage data are to be automatically taken. This is done with lines beginning with the keyword SNAPSHOT.

Each SNAPSHOT line must specify a particular subprogram in the usual manner, just as is done for a COVERAGE line.

The remainder of the SNAPSHOT line contains pairs, where each pair has a special identifier keyword followed by its own associated value. These pairs give supplementary information about the snapshot.

  • ON - This optional special identifier must be followed by the value ENTRY or EXIT, to denote that the snapshot is to be taken on entry to or exit from the subprogram respectively.
  • IS - This optional special identifier must be followed by an (arbitrarily long) string enclosed within quotation marks (""). It specifies a textual description or title that is to be logged along with the snapshot.

Here is an example of a SNAPSHOT directive:

SNAPSHOT "my_function" ON EXIT IS "my on exit snapshot"

A snapshot may also be taken dynamically from a custom probe by calling the ap_Brcov_DoSnapshot function provided by the test coverage API.

Configuration of TestNames

The branch coverage probe configuration file allows you to specify the name of some subprograms for which test names can be set. This is done with lines beginning with the keyword TESTNAME.

Each TESTNAME line must specify a particular subprogram in the usual manner, just as is done for a COVERAGE line.

The remainder of the TESTNAME line contains pairs, where each pair has a special identifier keyword followed by its own associated value. These pairs give supplementary information about the test name change.

  • ON - This optional special identifier must be followed by the value ENTRY or EXIT, to denote that the test name is to be set on entry to or exit from the subprogram respectively.
  • IS - This optional special identifier must be followed by an (arbitrarily long) string enclosed within quotation marks (""). It specifies a test name that is to be logged along with the snapshot.

Here is an example of a TESTNAME directive:

TESTNAME "my_function" ON ENTRY IS "test 1"

Configuration of TestName Hook Function

The branch coverage probe configuration file allows you to specify the name of some subprograms which are called when test name changes. The designated function should have a single (in) parameter which is a pointer to a nil-terminated string which is the test name. A value of NULL indicates no test name.

Each TESTNAMEHOOK line must specify a particular subprogram in the usual manner, just as is done for a COVERAGE line.

Here is an example of a TESTNAMEHOOK directive:

TESTNAMEHOOK "my_function"

If your test driver does not conform to the requirements of TESTNAME or TESTNAMEHOOK, you may write a custom probe using the ap_Brcov_SetTestName function provided by the Branch Coverage API.

Branch Coverage API

Users can control the behavior of the coverage probe by calls from within their own probes. The API for the trace probe is defined by [../include/coverage.h $APROBE/include/brcov.h]. Some of the functions exported by brcov.ual are:

  • ap_Brcov_Enable - Enables logging of coverage data.
  • ap_Brcov_Disable - Disables logging of coverage data.
  • ap_Brcov_DoSnapshot - Dumps current coverage information.
  • ap_Brcov_SetTestName - Sets the test name driving the current branch/edge coverage.

Branch Coverage Performance Issues

See Performance Issues for a general discussion of factors that affect performance.

The branch coverage probe is applied to the functions specified in the configuration file, so the run-time overhead is directly proportional to the number of calls to the functions selected and the number of branches executed in each function. The branch coverage probe simply increments an integer for each branch executed, so the amount of data is a constant multiple of the number of branches being covered, though additional snapshots increase this.

As branch coverage analysis is generally a unit-testing activity, it is mostly done on the small number of related functions under test, so performance should not be an issue. Application-wide branch coverage analysis during integration testing is not recommended.

Abrmerge

The results of multiple runs of brcov.ual (and coverage.ual) over the same executable may be merged into a single "combined summary" report using abrmerge.

A merged summary report is useful when running many tests, each with different input data or perhaps different probes, to force all logic paths to be executed. abrmerge can also merge branch data files to accumulate data from multiple runs into a single file.

A simple example

The test application is very simple. It just prints out a mini-menu and waits for you to select 1 or 2. Depending on your selection, it does one of two actions. You can see this in the DoProcessing() function in coverage_example.c. We want to exercise every branch in this function -- we refer to this as getting 100% coverage.

Here is coverage_example.c which should be saved in the local directory:

/* This is a simple example to demonstrate using brcov.ual with coverage.ual */
#include <stdio.h>
#include <stdlib.h>

/* This is the function we are interested in. */
void DoProcessing (void)
{
   int  Option = 0;
   char Buffer [100];
   
   printf ("1. Print string #1\n");
   printf ("2. Print string #2\n");
   
   while (Option < 1 || Option > 2)
   {
      printf ("      Enter your choice (1 or 2): \n");
      fgets (Buffer, 99, stdin);
      Option = atoi (Buffer);
   }
      
   switch (Option)
   {
   case 1:
      printf ("This is string #1 - pretty exciting, huh?!\n");
      break;

   case 2:
      printf ("This is string #2 - it doesn't get any better than this!\n");
      break;
   }
}

int main (int argc, char **argv)
{
   DoProcessing ();
   return 0;
}

Note that, unlike some other uses of Aprobe, branch and line coverage requires you to be familiar with (the lines in) your source code to make most effective use of the probe.

We can build the example as follows:

cc -g -v -o coverage_example coverage_example.c

Note: We need to create a configuration file for coverage.ual to direct it to produce coverage data compatible with brcov.ual. Create the following file coverage_example.coverage.cfg in the local directory:

PROBE CONFIGURATION FILE FOR COVERAGE VERSION 2.0.0
 
ProduceBrcovData TRUE
 
COVERAGE "main"

We can run the example as follows:

aprobe -u brcov -u coverage coverage_example

When the example application prompts you for a choice, enter the number 1. That will print out the first string and then the application will exit normally.

As before, aprobe stored the data in .apd files, so use apformat to format it:

apformat coverage_example

and abrmerge to merge and view it:

abrmerge *.brc *.c

Here's a portion of the report showing the line and branch coverage we've achieved:

pkg.adb:


+  - This line/branch/edge was not executed.
.  - This internal branch/edge was not executed but may not be significant.
*  - This line/branch/edge was not probed.

   Line    Edge/Branch   Line Cnt   Source
  ------   -----------   ---------  ------- - -
       1 :              :        : 
       2 :              :        : with Text_Io;
       3 :              :        : 
       4 :              :        : package body pkg is
       5 :              :        : 
       6 :              :        :   function Ident(i : integer) return integer is
       7 :              :        :   begin
       8 :              :        :      return i;
       9 :              :        :   end;
      10 :              :        : 
      11 :              :      2 :   procedure p1(I : in out integer) is
      12 :              :        :   begin
      13 :              :      2 :     if I = 0 then
          B       1x -> 16
      14 :              :      1 :       Text_Io.Put_Line("p1, 0!");
      15 :              :        :     else
      16 :              :      1 :       Text_Io.Put_Line("p1, not zero");
      17 :              :        :     end if;
      18 :              :      2 :   end p1;
      19 :              :        : 
      20 :              :      2 :   procedure p2(I : in out float) is
      21 :              :        :   begin
      22 :              :      2 :     if I < 0.000001 and then I > -0.000001 then
          B       1x -> 25
+         B       0x -> 25
      23 :              :      1 :       Text_Io.Put_Line("p2, 0!");
      24 :              :        :     else
      25 :              :      1 :       Text_Io.Put_Line("p2, not zero");
      26 :              :        :     end if;
      27 :              :      2 :   end p2;
      28 :              :        : 
      29 :              :        :   procedure td(i : in integer) is separate;
      30 :              :        : 
      31 :              :        : end pkg;
      32 :              :        : 

You can use the -q html option with abrmerge to produce HTML reports which use colors to highlight the coverage status of lines and branches as well as other information in hover test.

Using abrmerge

Sometimes we want to combine several test and branch coverage reports into a single report. Use abrmerge to accomplish this.

The above 2 lines that were not executed are specific to choice number 2. We could easily execute the lines of choice number 2 if we ran it again, but then we wouldn't be able to cover the choice 1 lines. If you look in the local directory, you'll see coverage_example.*.brc files. These were created at format time by the brcov and coverage predefined probes. These contain the branch and line coverage data obtained during choice 1, so let's save it.

We typically use abrmerge to merge results from many .brc files and display the combined data:

abrmerge -m combined.brc coverage_example.*.brc 

This "merges" the data in the input .brc files and outputs it in combined.brc.

Now run the application again using aprobe:

aprobe -u brcov -u coverage coverage_example

Select choice 2, then after the application ends re-run apformat:

apformat coverage_example

This time we get a different set of lines executed, as expected. Use the abrmerge command to combine the data in combined.brc (from the first run) with the data from this run (in a new coverage_example.*.brc):

abrmerge -m combined.brc coverage_example.*.brc combined.brc

Now we get the 100% coverage we wanted!

Branch Coverage Report

The branch coverage example report looks like this:

Aprobe Coverage Summary Report


Generated: 27 Nov 2017 09:19:05 -0500



--------------------------------------------------------------------------
Contents
--------------------------------------------------------------------------

TimeStamps
Overall Summary
Function TOC
File TOC
Function Summaries
Function Details
File Coverage



--------------------------------------------------------------------------
Timestmaps
--------------------------------------------------------------------------

TimeStamp:
Program   : /home/swn/aprobe/test/brcov/tnamec/main.exe
Host      : centos7
PID       : 13805
Start Time: 2017-11-27 09:19:06
End Time  : 2017-11-27 09:19:06



--------------------------------------------------------------------------
Overall Summary
--------------------------------------------------------------------------


                 Lines   Lines      Line                Branches  Branches            Branches  Branch
Total    Total   Not     Not        Coverage  Total     Not       Not        Branches Not       Coverage
Calls    Lines   Probed  Executed   Percent   Branches  Probed    Executed   Taken    Taken     Percent   Name
------- ------- -------- --------- ========= --------- --------- ---------- --------- --------- ======== --------- - -
     2       5        0         0       100         1         0          0         1         1      100  extern:"pkg.p1[1]"
     2       6        0         0       100         2         0          0         1         2      100  extern:"pkg.p2[1]"
    10      19        0         1        94         5         0          0         5         4      100  extern:"pkg.td[1]"

Note: Negative counts indicate the function/line was not instrumented.

          Funcs   Func                  Lines     Lines      Lines                 Branches   Branches              Branches   Branch
 Total    Not     Coverage    Total     Not       Not        Coverage   Total      Not        Not        Branches   Not        Coverage
 Funcs    Called  Percent     Lines     Probed    Executed   Percent    Branches   Probed     Executed   Taken      Taken      Percent 
-------- -------- ======== ---------- ---------- ---------- ========== ---------- ---------- ---------- ---------- ---------- ==========
      3        0      100         30          0          1         96          8          0          0          7          7        100



--------------------------------------------------------------------------
Function TOC
--------------------------------------------------------------------------

extern:"pkg.p1[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
extern:"pkg.p2[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg.adb)
extern:"pkg.td[1]" (/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)


--------------------------------------------------------------------------
File TOC
--------------------------------------------------------------------------

pkg.ads
pkg.adb
pkg-td.adb
main.adb


--------------------------------------------------------------------------
Function Coverage Summaries
--------------------------------------------------------------------------


extern:"pkg.p1[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg.adb)


Calls:  2
-----

Test Names: [ test p1 ]
----------

Lines:
-----
          Lines   Probed  Not Probed   Hit 
         ------- -------- ---------- ----------
Count:        5         5         0         5
Percent:              100         0       100


Branches:
--------
          Branches    Probed      Hit       Taken     NotTaken
         ---------- ---------- ---------- ---------- ----------
Count:            1          1          1          1          1
Percent:                   100        100        100        100


extern:"pkg.p2[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg.adb)


Calls:  2
-----

Test Names: [ test p1, test p2 ]
----------

Lines:
-----
          Lines   Probed  Not Probed   Hit 
         ------- -------- ---------- ----------
Count:        6         6         0         6
Percent:              100         0       100


Branches:
--------
          Branches    Probed      Hit       Taken     NotTaken
         ---------- ---------- ---------- ---------- ----------
Count:            2          2          2          1          2
Percent:                   100        100         50        100


extern:"pkg.td[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)


Calls:  10
-----

Test Names: [ test p1, test p2 ]
----------

Lines:
-----
          Lines   Probed  Not Probed   Hit 
         ------- -------- ---------- ----------
Count:       19        19         0        18
Percent:              100         0        94

    Lines Not Executed:
    ------------------
    21 / pkg-td.adb

Branches:
--------
          Branches    Probed      Hit       Taken     NotTaken
         ---------- ---------- ---------- ---------- ----------
Count:            5          5          5          5          4
Percent:                   100        100        100         80



--------------------------------------------------------------------------
Function Coverage Details
--------------------------------------------------------------------------


extern:"pkg.p1[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg.adb)

Lines:
-----
      Line     I     Count      File  [ Test Names ]
    ---------- -  -----------  ---------------------
            11 Y :          2 : pkg.adb [ test p1 ]
            13 Y :          2 : pkg.adb [ test p1 ]
            14 Y :          1 : pkg.adb [ test p1 ]
            16 Y :          1 : pkg.adb [ test p1 ]
            18 Y :          2 : pkg.adb [ test p1 ]

Branches:
--------
     Offset  I      Hit       Taken     NotTaken    Line/File -> Line/File  [ Test Names ]
    -------- -   ---------- ---------- ----------   --------------------------------------
    0x00000b Y :          2          1          1 : 13 / pkg.adb -> 16 / pkg.adb [ test p1 ]

Edges:
------
       Count     Offset/Line/File -> Offset/Line/File [ Test Names ]
    ----------  ---------------------------------------------------

extern:"pkg.p2[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg.adb)

Lines:
-----
      Line     I     Count      File  [ Test Names ]
    ---------- -  -----------  ---------------------
            20 Y :          2 : pkg.adb [ test p2 ]
            22 Y :          2 : pkg.adb [ test p2 ]
            22 Y :          1 : pkg.adb [ test p2 ]
            23 Y :          1 : pkg.adb [ test p2 ]
            25 Y :          1 : pkg.adb [ test p2 ]
            27 Y :          2 : pkg.adb [ test p2 ]

Branches:
--------
     Offset  I      Hit       Taken     NotTaken    Line/File -> Line/File  [ Test Names ]
    -------- -   ---------- ---------- ----------   --------------------------------------
    0x000013 Y :          2          1          1 : 22 / pkg.adb -> 25 / pkg.adb [ test p2 ]
    0x000021 Y :          1          0          1 : 22 / pkg.adb -> 25 / pkg.adb [ test p2 ]

Edges:
------
       Count     Offset/Line/File -> Offset/Line/File [ Test Names ]
    ----------  ---------------------------------------------------

extern:"pkg.td[1]"	(/home/swn/aprobe/test/brcov/tnamec/pkg-td.adb)

Lines:
-----
      Line     I     Count      File  [ Test Names ]
    ---------- -  -----------  ---------------------
             4 Y :         10 : pkg-td.adb [ test p1, test p2 ]
             5 Y :         10 : pkg-td.adb [ test p1, test p2 ]
             6 Y :         10 : pkg-td.adb [ test p1, test p2 ]
             7 Y :         10 : pkg-td.adb [ test p1, test p2 ]
             8 Y :         10 : pkg-td.adb [ test p1, test p2 ]
             9 Y :         10 : pkg-td.adb [ test p1, test p2 ]
            11 Y :         10 : pkg-td.adb [ test p1, test p2 ]
            21 Y :          0 : pkg-td.adb [  ]
            11 Y :          8 : pkg-td.adb [ test p1, test p2 ]
            21 Y :          6 : pkg-td.adb [ test p2 ]
            13 Y :          1 : pkg-td.adb [  ]
            22 Y :          1 : pkg-td.adb [ test p1 ]
            15 Y :          1 : pkg-td.adb [ test p1 ]
            22 Y :          1 : pkg-td.adb [ test p1 ]
            17 Y :          1 : pkg-td.adb [ test p1 ]
            22 Y :          1 : pkg-td.adb [ test p2 ]
            19 Y :          1 : pkg-td.adb [ test p2 ]
            22 Y :          1 : pkg-td.adb [ test p2 ]
            23 Y :         10 : pkg-td.adb [ test p1, test p2 ]

Branches:
--------
     Offset  I      Hit       Taken     NotTaken    Line/File -> Line/File  [ Test Names ]
    -------- -   ---------- ---------- ----------   --------------------------------------
    0x000037 Y :         10          1          9 : 11 / pkg-td.adb -> 15 / pkg-td.adb [ test p2, test p1 ]
    0x00003c Y :          9          8          1 : 11 / pkg-td.adb -> 11 / pkg-td.adb [ test p2, test p1 ]
    0x000041 Y :          1          1          0 : 11 / pkg-td.adb -> 13 / pkg-td.adb [  ]
    0x000048 Y :          8          1          7 : 11 / pkg-td.adb -> 17 / pkg-td.adb [ test p2, test p1 ]
    0x00004d Y :          7          1          6 : 11 / pkg-td.adb -> 19 / pkg-td.adb [ test p2 ]

Edges:
------
       Count     Offset/Line/File -> Offset/Line/File [ Test Names ]
    ----------  ---------------------------------------------------


--------------------------------------------------------------------------
File Coverage
--------------------------------------------------------------------------

pkg.ads:


+  - This line/branch/edge was not executed.
.  - This internal branch/edge was not executed but may not be significant.
*  - This line/branch/edge was not probed.

   Line    Edge/Branch   Line Cnt   Source
  ------   -----------   ---------  ------- - -
       1 :              :        : 
       2 :              :        : package pkg is
       3 :              :        : 
       4 :              :        :   procedure p1(I : in out integer);
       5 :              :        :   procedure p2(I : in out float);
       6 :              :        : 
       7 :              :        :   procedure td(I : in integer);
       8 :              :        : 
       9 :              :        : end pkg;
      10 :              :        : 

pkg.adb:


+  - This line/branch/edge was not executed.
.  - This internal branch/edge was not executed but may not be significant.
*  - This line/branch/edge was not probed.

   Line    Edge/Branch   Line Cnt   Source
  ------   -----------   ---------  ------- - -
       1 :              :        : 
       2 :              :        : with Text_Io;
       3 :              :        : 
       4 :              :        : package body pkg is
       5 :              :        : 
       6 :              :        :   function Ident(i : integer) return integer is
       7 :              :        :   begin
       8 :              :        :      return i;
       9 :              :        :   end;
      10 :              :        : 
      11 :              :      2 :   procedure p1(I : in out integer) is
      12 :              :        :   begin
      13 :              :      2 :     if I = 0 then
          B       1x -> 16
      14 :              :      1 :       Text_Io.Put_Line("p1, 0!");
      15 :              :        :     else
      16 :              :      1 :       Text_Io.Put_Line("p1, not zero");
      17 :              :        :     end if;
      18 :              :      2 :   end p1;
      19 :              :        : 
      20 :              :      2 :   procedure p2(I : in out float) is
      21 :              :        :   begin
      22 :              :      2 :     if I < 0.000001 and then I > -0.000001 then
          B       1x -> 25
+         B       0x -> 25
      23 :              :      1 :       Text_Io.Put_Line("p2, 0!");
      24 :              :        :     else
      25 :              :      1 :       Text_Io.Put_Line("p2, not zero");
      26 :              :        :     end if;
      27 :              :      2 :   end p2;
      28 :              :        : 
      29 :              :        :   procedure td(i : in integer) is separate;
      30 :              :        : 
      31 :              :        : end pkg;
      32 :              :        : 

pkg-td.adb:


+  - This line/branch/edge was not executed.
.  - This internal branch/edge was not executed but may not be significant.
*  - This line/branch/edge was not probed.

   Line    Edge/Branch   Line Cnt   Source
  ------   -----------   ---------  ------- - -
       1 :              :        : 
       2 :              :        : separate(pkg)
       3 :              :        : 
       4 :              :     10 : procedure td(i : in integer) is
       5 :              :     10 :   i0 : integer := 0;
       6 :              :     10 :   i1 : integer := 1;
       7 :              :     10 :   f0 : float := 0.0;
       8 :              :     10 :   f1 : float := 1.0;
       9 :              :     10 :   l  : integer := 0;
      10 :              :        : begin
      11 :              :     10 :   case i is
          B       1x -> 15
          B       1x -> 13
          B       1x -> 17
          B       1x -> 19
      12 :              :        :   when 1 =>
      13 :              :      1 :     p1(i0);
      14 :              :        :   when 2 =>
      15 :              :      1 :     p1(i1);
      16 :              :        :   when 3 =>
      17 :              :      1 :     p2(f0);
      18 :              :        :   when 4 =>
      19 :              :      1 :     p2(f1);
      20 :              :        :   when others =>
      21 :              :      6 :     null;
      22 :              :      1 :   end case;
      23 :              :     10 : end td;
      24 :              :        :   

main.adb:


+  - This line/branch/edge was not executed.
.  - This internal branch/edge was not executed but may not be significant.
*  - This line/branch/edge was not probed.

   Line    Edge/Branch   Line Cnt   Source
  ------   -----------   ---------  ------- - -
       1 :              :        : 
       2 :              :        : with Text_Io;
       3 :              :        : with pkg;
       4 :              :        : 
       5 :              :        : procedure Main is
       6 :              :        : begin
       7 :              :        :    for i in 1..10 loop
       8 :              :        :       pkg.td(i);
       9 :              :        :    end loop;
      10 :              :        : end Main;
      11 :              :        : 

Example D-3. Branch Coverage Summary Report

There is more information about interpreting the Branch Coverage Reports in Branch_Coverage_Cheat_Sheet.

Here is and example of the HTML branch coverage report:

Brcov example HTML.jpeg