read-normal read-bad-ptr read-boundary read-zero
                 write-normal write-bad-ptr write-boundary write-zero
                 multi-child-fd));
-put_file ("child-simple") if $test eq 'exec-once' or $test eq 'exec-multiple';
+put_file ("child-simple")
+    if grep ($_ eq $test,
+            qw (exec-once exec-multiple
+                join-simple join-twice));
 put_file ("child-arg") if $test eq 'exec-arg';
 put_file ("child-close") if $test eq 'multi-child-fd';
+put_file ("child-bad") if $test eq 'join-killed';
 
 sub put_file {
     my ($fn) = @_;
 
             write-normal write-bad-ptr write-boundary write-zero write-stdin
             write-bad-fd
             exec-once exec-arg exec-multiple exec-missing exec-bad-ptr
+            join-simple join-twice join-killed join-bad-pid
             multi-recurse multi-oom multi-child-fd
             ) unless @TESTS > 0;
 
        shift @output;
     }
     die "Only $n child processes started.\n" if $n < 15;
+
+    # There could be a death notice for a process that didn't get
+    # fully loaded, and/or notices from the loader.
+    while (@output > 0
+          && ($output[0] =~ /^\(multi-oom\) end $n$/
+              || $output[0] =~ /^load: /)) {
+       shift @output;
+    }
+
     while (--$n >= 0) {
        die "Output ended unexpectedly before process $n finished.\n"
            if @output < 2;
+
+       local ($_);
+       chomp ($_ = shift @output);
+       die "Found '$_' expecting 'end' message.\n" if !/^\(multi-oom\) end/;
        die "Child process $n ended out of order.\n"
-           if $output[0] !~ /^\(multi-oom\) end $n$/;
-       shift @output;
+           if !/^\(multi-oom\) end $n$/;
 
-       die "Child process $n didn't print proper exit message.\n"
-           if $output[0] !~ /^multi-oom: exit\($n\)$/;
-       shift @output;
+       chomp ($_ = shift @output);
+       die "Kernel didn't print proper exit message for process $n.\n"
+           if !/^multi-oom: exit\($n\)$/;
     }
     die "Spurious output at end: '$output[0]'.\n" if @output;
 }
     my (@output) = @_;
 
     # Fix up lines that look like exit codes.
+    # Exit codes are supposed to be printed in the form "process: exit(code)"
+    # but people get unfortunately creative with it.
     for my $i (0...$#output) {
-       if (my ($process, $code)
-           = $output[$i] =~ /^([-a-zA-Z0-9 ]+):.*[ \(](-?\d+)\b\)?$/) {
+       local ($_) = $output[$i];
+       
+       my ($process, $code);
+       if ((($process, $code) = /^([-a-zA-Z0-9 ]+):.*[ \(](-?\d+)\b\)?$/)
+           || (($process, $code) = /^([-a-zA-Z0-9 ]+) exit\((-?\d+)\)$/)
+           || (($process, $code)
+               = /^([-a-zA-Z0-9 ]+) \(.*\): exit\((-?\d+)\)$/)
+           || (($process, $code) = /^([-a-zA-Z0-9 ]+):\( (-?\d+) \) $/)
+) {
            $process = substr ($process, 0, 15);
            $process =~ s/\s.*//;
            $output[$i] = "$process: exit($code)\n";
 
        $details .= "Differences in `diff -u' format:\n";
        $details .= join ('', @diff);
-       $details .= "(This is considered a `fuzzy match'.)\n" if $fuzzy_match;
+       $details .= "(This is considered a `fuzzy match'.)\n"
+           if !$not_fuzzy_match;
     }
 
     $details{$test} = $details;