Skip to content

Commit 7e98c6c

Browse files
jgonzalezdroberpar
authored andcommitted
Exclusion of exception branches
- Added "--rc" option "geninfo_no_exception_branch" to make geninfo always ignore exception branches when collecting branch coverage data. - Added new markers LCOV_EXCL_EXCEPTION_BR_LINE, LCOV_EXCL_EXCEPTION_BR_START and LCOV_EXCL_EXCEPTION_BR_STOP to selectively disable in the source code the collection of exception branch data (to be used with lcov_branch_coverage=1). - Modified geninfo_intermediate=auto behavior to default to no intermediate file processing if geninfo_no_exception_branch is set and the intermediate file has text type, because the text intermediate format does not have the necessary branch info. Signed-off-by: Jesus Gonzalez <[email protected]>
1 parent 894cd88 commit 7e98c6c

File tree

4 files changed

+115
-12
lines changed

4 files changed

+115
-12
lines changed

bin/geninfo

Lines changed: 75 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,14 @@ our %ERROR_ID = (
9696
our $EXCL_START = "LCOV_EXCL_START";
9797
our $EXCL_STOP = "LCOV_EXCL_STOP";
9898

99-
# Marker to exclude branch coverage but keep function and line coveage
99+
# Marker to exclude branch coverage but keep function and line coverage
100100
our $EXCL_BR_START = "LCOV_EXCL_BR_START";
101101
our $EXCL_BR_STOP = "LCOV_EXCL_BR_STOP";
102102

103+
# Marker to exclude exception branch coverage but keep function, line coverage and non-exception branch coverage
104+
our $EXCL_EXCEPTION_BR_START = "LCOV_EXCL_EXCEPTION_BR_START";
105+
our $EXCL_EXCEPTION_BR_STOP = "LCOV_EXCL_EXCEPTION_BR_STOP";
106+
103107
# Compatibility mode values
104108
our $COMPAT_VALUE_OFF = 0;
105109
our $COMPAT_VALUE_ON = 1;
@@ -268,11 +272,13 @@ our %compat_value;
268272
our $gcno_split_crc;
269273
our $func_coverage = 1;
270274
our $br_coverage = 0;
275+
our $no_exception_br = 0;
271276
our $rc_auto_base = 1;
272277
our $rc_intermediate = "auto";
273278
our $intermediate;
274279
our $excl_line = "LCOV_EXCL_LINE";
275280
our $excl_br_line = "LCOV_EXCL_BR_LINE";
281+
our $excl_exception_br_line = "LCOV_EXCL_EXCEPTION_BR_LINE";
276282

277283
our $cwd = `pwd`;
278284
chomp($cwd);
@@ -339,10 +345,12 @@ if ($config || %opt_rc)
339345
"geninfo_adjust_src_path" => \$rc_adjust_src_path,
340346
"geninfo_auto_base" => \$rc_auto_base,
341347
"geninfo_intermediate" => \$rc_intermediate,
348+
"geninfo_no_exception_branch" => \$no_exception_br,
342349
"lcov_function_coverage" => \$func_coverage,
343350
"lcov_branch_coverage" => \$br_coverage,
344351
"lcov_excl_line" => \$excl_line,
345352
"lcov_excl_br_line" => \$excl_br_line,
353+
"lcov_excl_exception_br_line" => \$excl_exception_br_line,
346354
});
347355

348356
# Merge options
@@ -372,7 +380,7 @@ if ($config || %opt_rc)
372380
$adjust_src_replace = $replace;
373381
}
374382
}
375-
for my $regexp (($excl_line, $excl_br_line)) {
383+
for my $regexp (($excl_line, $excl_br_line, $excl_exception_br_line)) {
376384
eval 'qr/'.$regexp.'/';
377385
my $error = $@;
378386
chomp($error);
@@ -476,8 +484,9 @@ if ($rc_intermediate eq "0") {
476484
} elsif ($rc_intermediate eq "1") {
477485
$intermediate = 1;
478486
} elsif (lc($rc_intermediate) eq "auto") {
479-
# Use intermediate format if supported by gcov
480-
$intermediate = ($gcov_caps->{'intermediate-format'} ||
487+
# Use intermediate format if supported by gcov and not conflicting with
488+
# exception branch exclusion
489+
$intermediate = (($gcov_caps->{'intermediate-format'} && !$no_exception_br) ||
481490
$gcov_caps->{'json-format'}) ? 1 : 0;
482491
} else {
483492
die("ERROR: invalid value for geninfo_intermediate: ".
@@ -491,6 +500,15 @@ if ($intermediate) {
491500
"intermediate format - ignoring\n");
492501
$opt_derive_func_data = 0;
493502
}
503+
if ($no_exception_br && !$gcov_caps->{'json-format'}) {
504+
die("ERROR: excluding exception branches is not compatible with ".
505+
"text intermediate format\n");
506+
}
507+
}
508+
509+
if ($no_exception_br && ($gcov_version < $GCOV_VERSION_3_3_0)) {
510+
die("ERROR: excluding exception branches is not compatible with ".
511+
"gcov versions older than 3.3\n");
494512
}
495513

496514
# Determine gcov options
@@ -1843,7 +1861,9 @@ sub read_gcov_file($)
18431861
my $exclude_flag = 0;
18441862
my $exclude_line = 0;
18451863
my $exclude_br_flag = 0;
1864+
my $exclude_exception_br_flag = 0;
18461865
my $exclude_branch = 0;
1866+
my $exclude_exception_branch = 0;
18471867
my $last_block = $UNNAMED_BLOCK;
18481868
my $last_line = 0;
18491869
local *INPUT;
@@ -1913,6 +1933,13 @@ sub read_gcov_file($)
19131933
$exclude_branch = 0;
19141934
}
19151935
}
1936+
# Check for exclusion markers (exception branch exclude)
1937+
if (!$no_markers &&
1938+
/($EXCL_EXCEPTION_BR_STOP|$EXCL_EXCEPTION_BR_START|$excl_exception_br_line)/) {
1939+
warn("WARNING: $1 found at $filename:$last_line but ".
1940+
"branch exceptions exclusion is not supported with ".
1941+
"gcov versions older than 3.3\n");
1942+
}
19161943
# Source code execution data
19171944
if (/^\t\t(.*)$/)
19181945
{
@@ -1955,10 +1982,12 @@ sub read_gcov_file($)
19551982
# branches
19561983
$last_line = $2;
19571984
$last_block = $3;
1958-
} elsif (/^branch\s+(\d+)\s+taken\s+(\d+)/) {
1985+
} elsif (/^branch\s+(\d+)\s+taken\s+(\d+)(?:\s+\(([^)]*)\))?/) {
19591986
next if (!$br_coverage);
19601987
next if ($exclude_line);
19611988
next if ($exclude_branch);
1989+
next if (($exclude_exception_branch || $no_exception_br) &&
1990+
defined($3) && ($3 eq "throw"));
19621991
$branches = br_gvec_push($branches, $last_line,
19631992
$last_block, $1, $2);
19641993
} elsif (/^branch\s+(\d+)\s+never\s+executed/) {
@@ -2015,6 +2044,19 @@ sub read_gcov_file($)
20152044
$exclude_branch = 0;
20162045
}
20172046
}
2047+
# Check for exclusion markers (exception branch exclude)
2048+
if (!$no_markers) {
2049+
if (/$EXCL_EXCEPTION_BR_STOP/) {
2050+
$exclude_exception_br_flag = 0;
2051+
} elsif (/$EXCL_EXCEPTION_BR_START/) {
2052+
$exclude_exception_br_flag = 1;
2053+
}
2054+
if (/$excl_exception_br_line/ || $exclude_exception_br_flag) {
2055+
$exclude_exception_branch = 1;
2056+
} else {
2057+
$exclude_exception_branch = 0;
2058+
}
2059+
}
20182060

20192061
# Strip unexecuted basic block marker
20202062
$count =~ s/\*$//;
@@ -2051,7 +2093,7 @@ sub read_gcov_file($)
20512093
}
20522094

20532095
close(INPUT);
2054-
if ($exclude_flag || $exclude_br_flag) {
2096+
if ($exclude_flag || $exclude_br_flag || $exclude_exception_br_flag) {
20552097
warn("WARNING: unterminated exclusion section in $filename\n");
20562098
}
20572099
return(\@result, $branches, \@functions);
@@ -2137,6 +2179,7 @@ sub read_intermediate_json($$$)
21372179
# srcdata: filename -> [ excl, brexcl, checksums ]
21382180
# excl: lineno -> 1 for all lines for which to exclude all data
21392181
# brexcl: lineno -> 1 for all lines for which to exclude branch data
2182+
# 2 for all lines for which to exclude exception branch data
21402183
# checksums: lineno -> source code checksum
21412184
#
21422185
# Note: To simplify processing, gcov data is not combined here, that is counts
@@ -2211,7 +2254,7 @@ sub intermediate_text_to_info($$$)
22112254
$functions_hit++ if ($2 > 0);
22122255
} elsif ($line =~ /^branch:(\d+),(taken|nottaken|notexec)/) {
22132256
next if (!$br_coverage || $excl->{$1} ||
2214-
$brexcl->{$1});
2257+
(defined($brexcl->{$1}) && ($brexcl->{$1} == 1)));
22152258

22162259
# branch:<line>,taken|nottaken|notexec
22172260
if ($2 eq "taken") {
@@ -2255,6 +2298,7 @@ sub intermediate_text_to_info($$$)
22552298
# srcdata: filename -> [ excl, brexcl, checksums ]
22562299
# excl: lineno -> 1 for all lines for which to exclude all data
22572300
# brexcl: lineno -> 1 for all lines for which to exclude branch data
2301+
# 2 for all lines for which to exclude exception branch data
22582302
# checksums: lineno -> source code checksum
22592303
#
22602304
# Note: To simplify processing, gcov data is not combined here, that is counts
@@ -2338,15 +2382,20 @@ sub intermediate_json_to_info($$$)
23382382

23392383
$branch_num = 0;
23402384
# Branch data
2341-
if ($br_coverage && !$brexcl->{$line}) {
2385+
if ($br_coverage && (!defined($brexcl->{$line}) ||
2386+
($brexcl->{$line} != 1))) {
23422387
for my $b (@$branches) {
23432388
my $brcount = $b->{"count"};
2389+
my $is_exception = $b->{"throw"};
23442390

2345-
if (!defined($brcount) || $unexec) {
2346-
$brcount = "-";
2391+
if (!$is_exception || ((!defined($brexcl->{$line}) ||
2392+
($brexcl->{$line} != 2)) && !$no_exception_br)) {
2393+
if (!defined($brcount) || $unexec) {
2394+
$brcount = "-";
2395+
}
2396+
print($fd "BRDA:$line,0,$branch_num,".
2397+
"$brcount\n");
23472398
}
2348-
print($fd "BRDA:$line,0,$branch_num,".
2349-
"$brcount\n");
23502399

23512400
$branches_found++;
23522401
$branches_hit++ if ($brcount > 0);
@@ -2844,6 +2893,7 @@ sub get_source_data($)
28442893
my $flag = 0;
28452894
my %brdata;
28462895
my $brflag = 0;
2896+
my $exceptionbrflag = 0;
28472897
my %checksums;
28482898
local *HANDLE;
28492899

@@ -2865,13 +2915,26 @@ sub get_source_data($)
28652915
} elsif (/$EXCL_BR_START/) {
28662916
$brflag = 1;
28672917
}
2918+
if (/$EXCL_EXCEPTION_BR_STOP/) {
2919+
$exceptionbrflag = 0;
2920+
} elsif (/$EXCL_EXCEPTION_BR_START/) {
2921+
$exceptionbrflag = 1;
2922+
}
28682923
if (/$excl_br_line/ || $brflag) {
28692924
$brdata{$.} = 1;
2925+
} elsif (/$excl_exception_br_line/ || $exceptionbrflag) {
2926+
$brdata{$.} = 2;
28702927
}
28712928
if ($checksum) {
28722929
chomp();
28732930
$checksums{$.} = md5_base64($_);
28742931
}
2932+
if ($intermediate && !$gcov_caps->{'json-format'} &&
2933+
/($EXCL_EXCEPTION_BR_STOP|$EXCL_EXCEPTION_BR_START|$excl_exception_br_line)/) {
2934+
warn("WARNING: $1 found at $filename:$. but branch exceptions ".
2935+
"exclusion is not supported when using text intermediate ".
2936+
"format\n");
2937+
}
28752938
}
28762939
close(HANDLE);
28772940

lcovrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ geninfo_auto_base = 1
143143
# Use gcov intermediate format? Valid values are 0, 1, auto
144144
geninfo_intermediate = auto
145145

146+
# Specify if exception branches should be excluded from branch coverage.
147+
geninfo_no_exception_branch = 0
148+
146149
# Directory containing gcov kernel files
147150
# lcov_gcov_dir = /proc/gcov
148151

man/geninfo.1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,25 @@ Marks the end of a section which is excluded from branch coverage. The current
123123
line not part of this section.
124124
.RE
125125
.br
126+
LCOV_EXCL_EXCEPTION_BR_LINE
127+
.RS
128+
Lines containing this marker will be excluded from exception branch coverage:
129+
Exception branches will be ignored, but non-exception branches will not be
130+
affected.
131+
.br
132+
.RE
133+
LCOV_EXCL_EXCEPTION_BR_START
134+
.RS
135+
Marks the beginning of a section which is excluded from exception branch
136+
coverage. The current line is part of this section.
137+
.br
138+
.RE
139+
LCOV_EXCL_EXCEPTION_BR_STOP
140+
.RS
141+
Marks the end of a section which is excluded from exception branch coverage.
142+
The current line not part of this section.
143+
.RE
144+
.br
126145

127146
.SH OPTIONS
128147

man/lcovrc.5

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,15 @@ use immediate format when supported by gcov.
849849
Default is "auto".
850850
.PP
851851

852+
.BR geninfo_no_exception_branch " ="
853+
.IR 0 | 1
854+
.IP
855+
Specify whether to exclude exception branches from branch coverage.
856+
.br
857+
858+
Default is 0.
859+
.PP
860+
852861
.BR lcov_gcov_dir " ="
853862
.I path_to_kernel_coverage_data
854863
.IP
@@ -953,6 +962,15 @@ Specify the regular expression of lines to exclude from branch coverage.
953962
Default is 'LCOV_EXCL_BR_LINE'.
954963
.PP
955964

965+
.BR lcov_excl_exception_br_line " ="
966+
.I expression
967+
.IP
968+
Specify the regular expression of lines to exclude from exception branch coverage.
969+
.br
970+
971+
Default is 'LCOV_EXCL_EXCEPTION_BR_LINE'.
972+
.PP
973+
956974
.SH FILES
957975

958976
.TP

0 commit comments

Comments
 (0)