- unless (defined $file) {
- $file = $pm;
- return unless defined $pm;
- }
- my $callers = $args{callers};
- $callers = 12 unless defined $callers;
- $callers = int $callers;
- my $vg = Test::Valgrind::Suppressions::VG_PATH;
- if (!$vg || !-x $vg) {
- for (split /:/, $ENV{PATH}) {
- $_ .= '/valgrind';
- if (-x) {
- $vg = $_;
- last;
- }
- }
- if (!$vg) {
- $Test->plan(skip_all => 'No valgrind executable could be found in your path');
- return;
- }
- }
- pipe my $rdr, my $wtr or croak "pipe(\$rdr, \$wtr): $!";
- my $pid = fork;
- if (!defined $pid) {
- croak "fork(): $!";
- } elsif ($pid == 0) {
- setpgrp 0, 0 or croak "setpgrp(0, 0): $!";
- close $rdr or croak "close(\$rdr): $!";
- open STDERR, '>&', $wtr or croak "open(STDERR, '>&', \$wtr): $!";
- my @args = (
- '--tool=memcheck',
- '--leak-check=full',
- '--leak-resolution=high',
- '--num-callers=' . $callers,
- '--error-limit=yes'
- );
- unless ($args{no_supp}) {
- for (Test::Valgrind::Suppressions::supp_path(), $args{supp}) {
- push @args, '--suppressions=' . $_ if $_;
- }
- }
- if (defined $args{extra} and ref $args{extra} eq 'ARRAY') {
- push @args, @{$args{extra}};
- }
- push @args, $^X;
- push @args, '-I' . $_ for @INC;
- push @args, '-MTest::Valgrind=run,1', $file;
- print STDERR "valgrind @args\n" if $args{diag};
- local $ENV{PERL_DESTRUCT_LEVEL} = 3;
- local $ENV{PERL_DL_NONLAZY} = 1;
- exec $vg, @args;
- }
- close $wtr or croak "close(\$wtr): $!";
- local $SIG{INT} = sub { kill -(SIGTERM) => $pid };
- $Test->plan(tests => 5) unless $args{no_test};
- my @tests = (
- 'errors',
- 'definitely lost', 'indirectly lost', 'possibly lost', 'still reachable'