Skip to content

Commit a942cc2

Browse files
committed
genhtml: Add more demangler options
Function name demangling doesn't work when using LCOV in Cygwin to generate coverage for code compiled with MinGW-based compilers. The demangling tool must be changed to c++filt.exe and the command line option --no-strip-underscores must be specified. Provide new genhtml configuration file options to make these aspects configurable: # Name of the tool used for demangling C++ function names genhtml_demangle_cpp_tool = c++filt # Specify extra parameters to be passed to the demangling tool genhtml_demangle_cpp_params = "" Based on patch by Ion Gaztañaga <[email protected]> with the following changes: - Reword commit message - Use configuration file directives instead of new genhtml command line options - Remove unnecessary option checks - Change no_strip directive to more flexible params directive - Add directives to lcovrc sample file - Add description to lcovrc man page - Add tests Suggested-by: Ion Gaztañaga <[email protected]> Signed-off-by: Peter Oberparleiter <[email protected]>
1 parent 951b88a commit a942cc2

File tree

6 files changed

+197
-7
lines changed

6 files changed

+197
-7
lines changed

bin/genhtml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,8 @@ our $html_epilog; # Actual HTML epilog
287287
our $html_ext = "html"; # Extension for generated HTML files
288288
our $html_gzip = 0; # Compress with gzip
289289
our $demangle_cpp = 0; # Demangle C++ function names
290+
our $demangle_cpp_tool = "c++filt"; # Default demangler for C++ function names
291+
our $demangle_cpp_params = ""; # Extra parameters for demangling
290292
our @opt_ignore_errors; # Ignore certain error classes during processing
291293
our @ignore;
292294
our $opt_config_file; # User-specified configuration file location
@@ -379,6 +381,8 @@ if ($config || %opt_rc)
379381
"genhtml_charset" => \$charset,
380382
"genhtml_desc_html" => \$rc_desc_html,
381383
"genhtml_demangle_cpp" => \$demangle_cpp,
384+
"genhtml_demangle_cpp_tool" => \$demangle_cpp_tool,
385+
"genhtml_demangle_cpp_params" => \$demangle_cpp_params,
382386
"genhtml_missed" => \$opt_missed,
383387
"lcov_function_coverage" => \$lcov_func_coverage,
384388
"lcov_branch_coverage" => \$lcov_branch_coverage,
@@ -547,8 +551,8 @@ if ($frames)
547551
# Ensure that the c++filt tool is available when using --demangle-cpp
548552
if ($demangle_cpp)
549553
{
550-
if (system_no_output(3, "c++filt", "--version")) {
551-
die("ERROR: could not find c++filt tool needed for ".
554+
if (system_no_output(3, $demangle_cpp_tool, "--version")) {
555+
die("ERROR: could not find $demangle_cpp_tool tool needed for ".
552556
"--demangle-cpp\n");
553557
}
554558
}
@@ -5246,7 +5250,7 @@ sub demangle_list($)
52465250
my $tmpfile;
52475251
my $handle;
52485252
my %demangle;
5249-
my $demangle_arg = "";
5253+
my $demangle_arg = $demangle_cpp_params;
52505254
my %versions;
52515255

52525256
# Write function names to file
@@ -5257,12 +5261,12 @@ sub demangle_list($)
52575261

52585262
# Extra flag necessary on OS X so that symbols listed by gcov get demangled
52595263
# properly.
5260-
if ($^O eq "darwin") {
5264+
if ($demangle_arg eq "" && $^O eq "darwin") {
52615265
$demangle_arg = "--no-strip-underscores";
52625266
}
52635267

52645268
# Build translation hash from c++filt output
5265-
open($handle, "-|", "c++filt $demangle_arg < $tmpfile") or
5269+
open($handle, "-|", "$demangle_cpp_tool $demangle_arg < $tmpfile") or
52665270
die("ERROR: could not run c++filt: $!\n");
52675271
foreach my $func (@$list) {
52685272
my $translated = <$handle>;

lcovrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ genhtml_desc_html=0
102102
# Demangle C++ symbols
103103
#genhtml_demangle_cpp=1
104104

105+
# Name of the tool used for demangling C++ function names
106+
#genhtml_demangle_cpp_tool = c++filt
107+
108+
# Specify extra parameters to be passed to the demangling tool
109+
#genhtml_demangle_cpp_params = ""
110+
105111
# Location of the gcov tool (same as --gcov-info option of geninfo)
106112
#geninfo_gcov_tool = gcov
107113

man/lcovrc.5

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,16 @@ genhtml_desc_html=0
169169
#genhtml_demangle_cpp=1
170170
.br
171171

172+
# Name of the tool used for demangling C++ function names
173+
.br
174+
#genhtml_demangle_cpp_tool = c++filt
175+
.br
176+
177+
# Specify extra parameters to be passed to the demangling tool
178+
.br
179+
#genhtml_demangle_cpp_params = ""
180+
.br
181+
172182
# Location of the gcov tool
173183
.br
174184
#geninfo_gcov_tool = gcov
@@ -591,6 +601,32 @@ This option corresponds to the \-\-demangle\-cpp command line option of
591601
Default is 0.
592602
.PP
593603

604+
.BR genhtml_demangle_cpp_tool " ="
605+
.I path_to_c++filt
606+
.IP
607+
Specify the location of the demangle tool (see
608+
.BR c++filt (1))
609+
used to convert C++ internal function names to human readable format
610+
for display on the HTML function overview page.
611+
.br
612+
613+
Default is 'c++filt'.
614+
.PP
615+
616+
.BR genhtml_demangle_cpp_params " ="
617+
.I parameters
618+
.IP
619+
Specify extra parameters to be passed to the demangling tool
620+
621+
Use this option if your environment requires additional parameters such
622+
as --no-strip-underscore for correctly demangling C++ internal function
623+
names. See also
624+
.BR c++filt (1)).
625+
.br
626+
627+
Default is "".
628+
.PP
629+
594630
.BR genhtml_desc_html " ="
595631
.IR 0 | 1
596632
.IP

tests/genhtml/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include ../common.mak
22

3-
TESTS := full.sh part1.sh part2.sh target.sh zero.sh
3+
TESTS := full.sh part1.sh part2.sh target.sh zero.sh demangle.sh
44

55
clean:
6-
rm -rf *.log out_*
6+
rm -rf *.log out_* *.tmp

tests/genhtml/demangle.sh

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Check demangling options
4+
# genhtml_demangle_cpp
5+
# genhtml_demangle_cpp_tool
6+
# genhtml_demangle_cpp_params
7+
#
8+
9+
OUTDIR="out_demangle"
10+
STDOUT="demangle_stdout.log"
11+
STDERR="demangle_stderr.log"
12+
INFO="demangle.info.tmp"
13+
SOURCE="file.tmp"
14+
HTML="${OUTDIR}/genhtml/${SOURCE}.func.html"
15+
MYFILT="${PWD}/mycppfilt.sh"
16+
17+
function die() {
18+
echo "Error: $*" >&2
19+
exit 1
20+
}
21+
22+
function cleanup() {
23+
rm -rf "${OUTDIR}" "${INFO}" "${SOURCE}"
24+
}
25+
26+
function prepare() {
27+
cat >"${INFO}" <<EOF
28+
SF:$SOURCE
29+
FN:1,myfunc1
30+
FN:2,_Z7myfunc2v
31+
FN:3,__Z7myfunc3v
32+
DA:1,1
33+
end_of_record
34+
EOF
35+
touch "${SOURCE}"
36+
}
37+
38+
function run() {
39+
local CMDLINE="${GENHTML} ${INFO} -o ${OUTDIR} $*"
40+
41+
rm -rf "${OUTDIR}"
42+
43+
# Run genhtml
44+
echo "CMDLINE: $CMDLINE"
45+
$CMDLINE >${STDOUT} 2>${STDERR}
46+
RC=$?
47+
48+
echo "STDOUT_START"
49+
cat ${STDOUT}
50+
echo "STDOUT_STOP"
51+
52+
echo "STDERR_START"
53+
cat ${STDERR}
54+
echo "STDERR_STOP"
55+
56+
# Check exit code
57+
[[ $RC -ne 0 ]] && die "Non-zero genhtml exit code $RC"
58+
59+
# Output must not contain warnings
60+
if [[ -s ${STDERR} ]] ; then
61+
echo "Error: Output on stderr.log:"
62+
cat ${STDERR}
63+
exit 1
64+
fi
65+
66+
# Log function names
67+
echo "Found function names:"
68+
grep coverFn ${HTML}
69+
}
70+
71+
prepare
72+
73+
echo "Run 1: No demangling"
74+
run ""
75+
if grep -q myfunc1 ${HTML} ; then
76+
echo "Success - found myfunc1"
77+
else
78+
die "Missing function name 'myfunc1' in output"
79+
fi
80+
81+
echo
82+
echo "Run 2: Demangle using defaults"
83+
if type -P c++filt >/dev/null ; then
84+
# Depending on environment, encoded symbols are converted to either
85+
# myfunc2() or myfunc3()
86+
run "--demangle-cpp"
87+
if grep -q 'myfunc[23]()' ${HTML} ; then
88+
echo "Success - found myfunc[23]() converted by c++filt"
89+
else
90+
die "Missing converted function name 'myfunc[23]()' in output"
91+
fi
92+
else
93+
echo "Skipping - missing c++filt tool"
94+
fi
95+
96+
echo
97+
echo "Run 3: Demangle using custom demangling tool"
98+
# mycppfilt.sh with no parameters prepends aaa to each function name
99+
run "--demangle-cpp --rc genhtml_demangle_cpp_tool=$MYFILT"
100+
if grep -q 'aaamyfunc' ${HTML} ; then
101+
echo "Success - found myfunc prefixed by mycppfilt.sh"
102+
else
103+
die "Missing converted function name 'aaamyfunc' in output"
104+
fi
105+
106+
echo
107+
echo "Run 4: Demangle with params set"
108+
# mycppfilt.sh with parameter prepends that parameter to to each function name
109+
run "--demangle-cpp --rc genhtml_demangle_cpp_tool=$MYFILT --rc genhtml_demangle_cpp_params='bbb'"
110+
if grep -q 'bbbmyfunc' ${HTML} ; then
111+
echo "Success - found myfunc prefixed by custom prefix"
112+
else
113+
die "Missing converted function name 'bbbmyfunc' in output"
114+
fi
115+
116+
# Success
117+
cleanup
118+
119+
exit 0

tests/genhtml/mycppfilt.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Dummy c++filt replacement for testing purpose
4+
#
5+
6+
# Skip over any valid options
7+
while [[ $1 =~ ^- ]] ; do
8+
shift
9+
done
10+
11+
if [[ -n "$*" ]] ; then
12+
PREFIX="$*"
13+
else
14+
PREFIX="aaa"
15+
fi
16+
17+
while read LINE ; do
18+
echo "${PREFIX}${LINE}"
19+
unset LINE
20+
done
21+
22+
# Last line isn't newline-terminated
23+
[[ -n "${LINE}" ]] && echo "${PREFIX}${LINE}"
24+
25+
exit 0

0 commit comments

Comments
 (0)