Description
Inspired by some discussion on #p5p, I decided to try to build a perl
on Linux (Debian 11) with clang
and ASAN. I make no claim to knowing what I'm doing in ASAN territory; I did not have any clear idea of what the results would be. I found that when I configured with arguments similar to those used in George Greer's smoke-testing reports (e.g., https://perl5.test-smoke.org/report/5030661), I was able to get at least as far as building miniperl with ASAN and unthreaded builds -- but not with threaded builds.
Threaded builds
I've tried the following at tags v5.34.0 and v5.36.0 as well as blead.
sh ./Configure -des -Dusedevel -Dcc=clang \
-Accflags="-g -fno-omit-frame-pointer -fsanitize=address -fno-common -fsanitize-blacklist=`pwd`/asan_ignore" -Aldflags="-fsanitize=address" \
-Duseithreads \
&& make miniperl
Compilation failed like this:
...
opmini.o perlmini.o gv.o toke.o perly.o pad.o regcomp.o dump.o util.o mg.o reentr.o mro_core.o keywords.o hv.o av.o run.o pp_hot.o sv.o pp.o scope.o pp_ctl.o pp_sys.o doop.o doio.o regexec.o utf8.o taint.o deb.o universal.o globals.o perlio.o numeric.o mathoms.o locale.o pp_pack.o pp_sort.o caretx.o dquote.o time64.o miniperlmain.o -lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
./miniperl -w -Ilib -Idist/Exporter/lib -MExporter -e '<?>' || sh -c 'echo >&2 Failed to build miniperl. Please run make minitest; exit 1'
=================================================================
==747495==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4072 byte(s) in 1 object(s) allocated from:
#0 0x49ce02 in calloc (/home/jkeenan/gitwork/perl/miniperl+0x49ce02)
... followed by a long list of direct and indirect leaks.
Unthreaded builds
If I simply dropped the -Duseithreads
from the configuration, miniperl would build on v5.34.0, v5.36.0 and blead (v5.37.8-172-gd0613d9c78
).
$ clang --version | head -1
Debian clang version 11.0.1-2
On v5.34.0
, in the ASAN unthreaded build, I got 2 test failures in make test_harness
:
Test Summary Report
-------------------
re/pat.t (Wstat: 9 Tests: 108 Failed: 0)
Non-zero wait status: 9
Parse errors: Bad plan. You planned 1022 tests but ran 108.
../cpan/Encode/t/mime-header.t (Wstat: 9 Tests: 207 Failed: 0)
Non-zero wait status: 9
Parse errors: Bad plan. You planned 266 tests but ran 207.
Files=2667, Tests=1185872, 2052 wallclock secs (205.45 usr 77.94 sys + 1519.58 cusr 382.20 csys = 2185.17 CPU)
Result: FAIL
make: *** [makefile:839: test_harness] Error 2
However, when I tested just those two files, I got a PASS.
$ cd t; TEST_JOBS=1 ./perl harness re/pat.t ../cpan/Encode/t/mime-header.t; cd -
re/pat.t ........................ ok
../cpan/Encode/t/mime-header.t .. ok
All tests successful.
Files=2, Tests=1288, 119 wallclock secs ( 0.20 usr 0.02 sys + 33.00 cusr 85.63 csys = 118.85 CPU)
Result: PASS
(I didn't completely test v5.36.0
.)
On blead, in the ASAN unthreaded build, I got 4 test failures:
$ git describe; ./perl -Ilib -V:config_args
v5.37.8-172-gd0613d9c78
config_args='-des -Dusedevel -Dcc=clang -Accflags=-g -fno-omit-frame-pointer -fsanitize=address -fno-common -fsanitize-blacklist=/home/jkeenan/gitwork/perl/asan_ignore -Aldflags=-fsanitize=address';
...
Test Summary Report
-------------------
re/bigfuzzy_not_utf8.t (Wstat: 0 Tests: 1 Failed: 1)
Failed test: 1
re/pat.t (Wstat: 9 (Signal: KILL) Tests: 276 Failed: 0)
Non-zero wait status: 9
Parse errors: Bad plan. You planned 1230 tests but ran 276.
re/pat_psycho.t (Wstat: 9 (Signal: KILL) Tests: 1 Failed: 0)
Non-zero wait status: 9
Parse errors: Bad plan. You planned 15 tests but ran 1.
../lib/warnings.t (Wstat: 0 Tests: 940 Failed: 1)
Failed test: 380
Files=2738, Tests=1180601, 1983 wallclock secs (193.95 usr 69.90 sys + 1533.20 cusr 347.26 csys = 2144.31 CPU)
Result: FAIL
Finished test run at Tue Feb 14 23:59:37 2023.
make: *** [makefile:865: test_harness] Error 2
Re-running just the failing files, I got 3 PASSes and 1 FAIL.
$ cd t; TEST_JOBS=1 ./perl harness re/bigfuzzy_not_utf8.t re/pat.t re/pat_psycho.t ../lib/warnings.t; cd -
re/bigfuzzy_not_utf8.t .. ok
re/pat.t ................ ok
re/pat_psycho.t ......... ok
../lib/warnings.t ....... 356/940 FILE: lib/warnings/class ; line 13
PROG:
# constructor warnings
use v5.36;
use feature 'class';
no warnings 'experimental::class';
class C { }
C->new();
eval { C->new('foo') }; # suppress error
EXPECTED:
Odd number of arguments passed to "C" constructor at - line 7.
GOT:
Odd number of arguments passed to "C" constructor at - line 7.
=================================================================
==857841==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 1 byte(s) in 1 object(s) allocated from:
#0 0x4b1bcd in malloc (/home/jkeenan/gitwork/perl/perl+0x4b1bcd)
#1 0x749e54 in Perl_safesysmalloc /home/jkeenan/gitwork/perl/util.c:161:21
#2 0x7949d7 in Perl_newSVobject /home/jkeenan/gitwork/perl/class.c:40:5
#3 0x796234 in injected_constructor /home/jkeenan/gitwork/perl/class.c:162:20
#4 0x7dea53 in Perl_pp_entersub /home/jkeenan/gitwork/perl/pp_hot.c:5518:9
#5 0x7bb319 in Perl_runops_standard /home/jkeenan/gitwork/perl/run.c:41:26
#6 0x55639e in S_run_body /home/jkeenan/gitwork/perl/perl.c
#7 0x555751 in perl_run /home/jkeenan/gitwork/perl/perl.c:2722:9
#8 0x4e19ae in main /home/jkeenan/gitwork/perl/perlmain.c:127:9
#9 0x7f6e22f5ad09 in __libc_start_main csu/../csu/libc-start.c:308:16
SUMMARY: AddressSanitizer: 1 byte(s) leaked in 1 allocation(s).
# Failed test 380 - test from lib/warnings/class at line 13 at lib/warnings/class line 13
../lib/warnings.t ....... 933/940 #
# Note: 'run_multiple_progs' run has one or more failures
# you can consider setting the environment variable
# PERL_TEST_ABORT_FIRST_FAILURE=1 before running the test
# to stop on the first error.
#
../lib/warnings.t ....... Failed 1/940 subtests
(less 1 skipped subtest: 938 okay)
Test Summary Report
-------------------
../lib/warnings.t (Wstat: 0 Tests: 940 Failed: 1)
Failed test: 380
Files=4, Tests=2186, 126 wallclock secs ( 0.57 usr 0.09 sys + 46.67 cusr 78.61 csys = 125.94 CPU)
To what extent are these results plausible? First, failure to get as far as miniperl
with clang, ASAN and threads?
Second, inconsistent test failures with ASAN but without threads?