@@ -93,13 +93,23 @@ for my $envname (@bad_env_vars) {
93
93
}
94
94
}
95
95
96
+ # Location to put the Valgrind log.
97
+ our $Valgrind_Log ;
98
+
99
+ my %skip = (
100
+ ' .' => 1,
101
+ ' ..' => 1,
102
+ ' CVS' => 1,
103
+ ' RCS' => 1,
104
+ ' SCCS' => 1,
105
+ ' .svn' => 1,
106
+ );
107
+
108
+
96
109
if ($: :do_nothing) {
97
110
return 1;
98
111
}
99
112
100
- # Location to put the Valgrind log.
101
- our $Valgrind_Log ;
102
-
103
113
$| = 1;
104
114
105
115
# for testing TEST only
@@ -149,15 +159,6 @@ $ENV{EMXSHELL} = 'sh'; # For OS/2
149
159
if ($show_elapsed_time ) { require Time::HiRes }
150
160
my %timings = (); # testname => [@et] pairs if $show_elapsed_time.
151
161
152
- my %skip = (
153
- ' .' => 1,
154
- ' ..' => 1,
155
- ' CVS' => 1,
156
- ' RCS' => 1,
157
- ' SCCS' => 1,
158
- ' .svn' => 1,
159
- );
160
-
161
162
# Roll your own File::Find!
162
163
sub _find_tests { our @found =(); push @ARGV , _find_files(' \.t$' , $_ [0]) }
163
164
sub _find_files {
@@ -284,16 +285,19 @@ sub _cmd {
284
285
if ($ENV {PERL_VALGRIND }) {
285
286
my $perl_supp = $options -> {return_dir } ? " $options ->{return_dir}/perl.supp" : " perl.supp" ;
286
287
my $valgrind_exe = $ENV {VALGRIND } // ' valgrind' ;
288
+ if ($options -> {run_dir }) {
289
+ $Valgrind_Log = " $options ->{run_dir}/$Valgrind_Log " ;
290
+ }
287
291
my $vg_opts = $ENV {VG_OPTS }
288
- // ' --log-fd=3 '
292
+ // " --log-file= $Valgrind_Log "
289
293
. " --suppressions=$perl_supp --leak-check=yes "
290
294
. " --leak-resolution=high --show-reachable=yes "
291
- . " --num-callers=50 --track-origins=yes" ;
295
+ . " --num-callers=50 --track-origins=yes" ;
296
+ # Force logging if not asked for (so cachegrind reporting works below)
297
+ if ($vg_opts !~ / --log-file/ ) {
298
+ $vg_opts = " --log-file=$Valgrind_Log $vg_opts " ;
299
+ }
292
300
$perl = " $valgrind_exe $vg_opts $perl " ;
293
- $redir = " 3>$Valgrind_Log " ;
294
- if ($options -> {run_dir }) {
295
- $Valgrind_Log = " $options ->{run_dir}/$Valgrind_Log " ;
296
- }
297
301
}
298
302
299
303
my $args = " $options ->{testswitch} $options ->{switch} $options ->{utf8}" ;
@@ -310,6 +314,16 @@ sub _before_fork {
310
314
chdir $run_dir or die " Can't chdir to '$run_dir ': $! " ;
311
315
}
312
316
317
+ # Remove previous valgrind output otherwise it will interfere
318
+ my $test = $options -> {test };
319
+
320
+ (local $Valgrind_Log = " $test .valgrind-current" ) =~ s / ^.*\/ // ;
321
+
322
+ if ($ENV {PERL_VALGRIND } && -e $Valgrind_Log ) {
323
+ unlink $Valgrind_Log
324
+ or warn " $0 : Failed to unlink '$Valgrind_Log ': $! \n " ;
325
+ }
326
+
313
327
return ;
314
328
}
315
329
553
567
$te = ' ' ;
554
568
}
555
569
556
- (local $Valgrind_Log = " $test .valgrind-current" ) =~ s / ^.*\/ // ;
570
+ (local $Valgrind_Log = " $test .valgrind-current" ) =~ s / ^.*\/ // ;
571
+
557
572
my $results = _run_test($test , $type );
558
573
559
574
my $failure ;
653
668
$failure = ' FAILED--no leader found' unless $seen_leader ;
654
669
}
655
670
656
- if ($ENV {PERL_VALGRIND }) {
657
- $toolnm = $ENV {VALGRIND };
658
- $toolnm =~ s | .*/|| ; # keep basename
659
- my @valgrind ; # gets content of file
660
- if (-e $Valgrind_Log ) {
661
- if (open (V, $Valgrind_Log )) {
662
- @valgrind = <V>;
663
- close V;
664
- } else {
665
- warn " $0 : Failed to open '$Valgrind_Log ': $! \n " ;
666
- }
667
- }
668
- if ($ENV {VG_OPTS } =~ / (cachegrind)/ or $toolnm =~ / (perf)/ ) {
669
- $toolnm = $1 ;
670
- if ($toolnm eq ' perf' ) {
671
- # append perfs subcommand, not just stat
672
- my ($sub ) = split /\s /, $ENV {VG_OPTS };
673
- $toolnm .= " -$sub " ;
674
- }
675
- if (rename $Valgrind_Log , " $test .$toolnm " ) {
676
- $grind_ct ++;
677
- } else {
678
- warn " $0 : Failed to create '$test .$toolnm ': $! \n " ;
679
- }
680
- }
681
- elsif (@valgrind ) {
682
- my $leaks = 0;
683
- my $errors = 0;
684
- for my $i (0..$#valgrind ) {
685
- local $_ = $valgrind [$i ];
686
- if (/ ^==\d +== ERROR SUMMARY: (\d +) errors? / ) {
687
- $errors = $errors + $1 ; # there may be multiple error summaries
688
- } elsif (/ ^==\d +== LEAK SUMMARY:/ ) {
689
- for my $off (1 .. 4) {
690
- if ($valgrind [$i +$off ] =~
691
- / (?:lost|reachable):\s +\d + bytes in (\d +) blocks/ ) {
692
- $leaks = $leaks + $1 ;
693
- }
694
- }
695
- }
696
- }
697
- if ($errors or $leaks ) {
698
- if (rename $Valgrind_Log , " $test .valgrind" ) {
699
- $grind_ct = $grind_ct + 1;
700
- } else {
701
- warn " $0 : Failed to create '$test .valgrind': $! \n " ;
702
- }
703
- }
704
- } else {
705
- warn " No valgrind output?\n " ;
706
- }
707
- if (-e $Valgrind_Log ) {
708
- unlink $Valgrind_Log
709
- or warn " $0 : Failed to unlink '$Valgrind_Log ': $! \n " ;
710
- }
711
- }
671
+ _check_valgrind(\$toolnm , \$grind_ct , \$test );
672
+
712
673
if ($type eq ' deparse' ) {
713
674
unlink " ./$test .dp" ;
714
675
}
@@ -830,16 +791,8 @@ SHRDLU_5
830
791
print " wrote storable file: $fn \n " ;
831
792
}
832
793
}
833
- if ($ENV {PERL_VALGRIND }) {
834
- my $s = $grind_ct == 1 ? ' ' : ' s' ;
835
- print " $grind_ct valgrind report$s created.\n " , ;
836
- if ($toolnm eq ' cachegrind' ) {
837
- # cachegrind leaves a lot of cachegrind.out.$pid litter
838
- # around the tree, find and delete them
839
- unlink _find_files(' cachegrind.out.\d+$' ,
840
- qw ( ../t ../cpan ../ext ../dist/ ) );
841
- }
842
- }
794
+
795
+ _cleanup_valgrind(\$toolnm , \$grind_ct );
843
796
}
844
797
exit ($: :bad_files != 0);
845
798
@@ -874,4 +827,82 @@ sub gather_conf_platform_info {
874
827
);
875
828
}
876
829
830
+ sub _check_valgrind {
831
+ return unless $ENV {PERL_VALGRIND };
832
+
833
+ my ($toolnm , $grind_ct , $test ) = @_ ;
834
+
835
+ $$toolnm = $ENV {VALGRIND };
836
+ $$toolnm =~ s | .*/|| ; # keep basename
837
+ my @valgrind ; # gets content of file
838
+ if (-e $Valgrind_Log ) {
839
+ if (open (V, $Valgrind_Log )) {
840
+ @valgrind = <V>;
841
+ close V;
842
+ } else {
843
+ warn " $0 : Failed to open '$Valgrind_Log ': $! \n " ;
844
+ }
845
+ }
846
+ if ($ENV {VG_OPTS } =~ / (cachegrind)/ or $$toolnm =~ / (perf)/ ) {
847
+ $$toolnm = $1 ;
848
+ if ($$toolnm eq ' perf' ) {
849
+ # append perfs subcommand, not just stat
850
+ my ($sub ) = split /\s /, $ENV {VG_OPTS };
851
+ $$toolnm .= " -$sub " ;
852
+ }
853
+ if (rename $Valgrind_Log , " $$test .$$toolnm " ) {
854
+ $$grind_ct ++;
855
+ } else {
856
+ warn " $0 : Failed to create '$$test .$$toolnm ': $! \n " ;
857
+ }
858
+ }
859
+ elsif (@valgrind ) {
860
+ my $leaks = 0;
861
+ my $errors = 0;
862
+ for my $i (0..$#valgrind ) {
863
+ local $_ = $valgrind [$i ];
864
+ if (/ ^==\d +== ERROR SUMMARY: (\d +) errors? / ) {
865
+ $errors = $errors + $1 ; # there may be multiple error summaries
866
+ } elsif (/ ^==\d +== LEAK SUMMARY:/ ) {
867
+ for my $off (1 .. 4) {
868
+ if ($valgrind [$i +$off ] =~
869
+ / (?:lost|reachable):\s +\d + bytes in (\d +) blocks/ ) {
870
+ $leaks = $leaks + $1 ;
871
+ }
872
+ }
873
+ }
874
+ }
875
+ if ($errors or $leaks ) {
876
+ if (rename $Valgrind_Log , " $$test .valgrind" ) {
877
+ $$grind_ct = $$grind_ct + 1;
878
+ } else {
879
+ warn " $0 : Failed to create '$$test .valgrind': $! \n " ;
880
+ }
881
+ }
882
+ } else {
883
+ # Quiet wasn't asked for? Something may be amiss
884
+ if ($ENV {VG_OPTS } && $ENV {VG_OPTS } !~ / (^|\s )(-q|--quiet)(\s |$) / ) {
885
+ warn " No valgrind output?\n " ;
886
+ }
887
+ }
888
+ if (-e $Valgrind_Log ) {
889
+ unlink $Valgrind_Log
890
+ or warn " $0 : Failed to unlink '$Valgrind_Log ': $! \n " ;
891
+ }
892
+ }
893
+
894
+ sub _cleanup_valgrind {
895
+ return unless $ENV {PERL_VALGRIND };
896
+
897
+ my ($toolnm , $grind_ct ) = @_ ;
898
+ my $s = $$grind_ct == 1 ? ' ' : ' s' ;
899
+ print " $$grind_ct valgrind report$s created.\n " , ;
900
+ if ($$toolnm eq ' cachegrind' ) {
901
+ # cachegrind leaves a lot of cachegrind.out.$pid litter
902
+ # around the tree, find and delete them
903
+ unlink _find_files(' cachegrind.out.\d+$' ,
904
+ qw ( ../t ../cpan ../ext ../dist/ ) );
905
+ }
906
+ }
907
+
877
908
# ex: set ts=8 sts=4 sw=4 noet:
0 commit comments