+ local $@;
+ eval {
+ local $SIG{INT} = sub {
+ die 'valgrind analysis was interrupted';
+ };
+
+ close $vwtr or $self->_croak("close(\$vwtr): $!");
+ close $ewtr or $self->_croak("close(\$ewtr): $!");
+
+ SEL: {
+ my $sel = IO::Select->new($vrdr, $erdr);
+
+ my $child_err;
+ while (my @ready = $sel->can_read) {
+ last SEL if @ready == 1 and fileno $ready[0] == fileno $vrdr;
+
+ my $buf;
+ my $bytes_read = sysread $erdr, $buf, 4096;
+ if (not defined $bytes_read) {
+ $self->_croak("sysread(\$erdr): $!");
+ } elsif ($bytes_read) {
+ $sel->remove($vrdr) unless $child_err;
+ $child_err .= $buf;
+ } else {
+ $sel->remove($erdr);
+ die $child_err if $child_err;
+ }
+ }
+ }
+
+ my $aborted = $self->parser->parse($self, $vrdr);
+
+ if ($aborted) {
+ $self->report($self->report_class->new_diag("valgrind has aborted"));
+ return 0;
+ }
+
+ 1;
+ } or do {
+ $error = $@;
+ kill -(POSIX::SIGKILL()) => $pid if kill 0 => $pid;
+ close $erdr;
+ close $vrdr;
+ waitpid $pid, 0;
+ # Force the guard destructor to trigger now so that old perls don't lose $@
+ last GUARDED;
+ };