Fix treatment of timeouts in run-tests and pintos.
[pintos-anon] / grading / vm / run-tests
index 42e198b02f8a3dd2da5213f0f30291b4a78c09f5..b6987fe000e012fc2eadfeaaa437794836d8d55f 100755 (executable)
@@ -265,7 +265,8 @@ sub really_run_test {
             . "--swap-disk=output/$test/swap.dsk "
             . "-v run -q -ex \"$test$testargs\"",
             LOG => "$test/run",
-            TIMEOUT => $timeout)
+            TIMEOUT => $timeout,
+            EXPECT => 1)
        or return "Bochs error";
     
     return "ok";
@@ -683,9 +684,7 @@ sub xsystem {
        die "fork: $!\n" if !defined $pid;
        if (!$pid) {
            if (defined $log) {
-               close STDOUT;
                open (STDOUT, ">output/$log.out");
-               close STDERR;
                open (STDERR, ">output/$log.err");
            }
            exec ($command);
@@ -695,24 +694,36 @@ sub xsystem {
        $status = $?;
        alarm 0;
     };
+
+    my ($ok);
     if ($@) {
        die unless $@ eq "alarm\n";   # propagate unexpected errors
-       print "Timed out $pid.\n";
-       print "not killed\n" if !kill ('SIGTERM', $pid);
-       $status = 0;
-    }
+       print "Timed out: ";
+       for (my ($i) = 0; $i < 10; $i++) {
+           kill ('SIGTERM', $pid);
+           sleep (1);
+           my ($retval) = waitpid ($pid, WNOHANG);
+           last if $retval == $pid || $retval == -1;
+           print "Waiting for $pid to die" if $i == 0;
+           print ".";
+       }
+       $ok = 1;
+    } else {
+       if (WIFSIGNALED ($status)) {
+           my ($signal) = WTERMSIG ($status);
+           die "Interrupted\n" if $signal == SIGINT;
+           print "Child terminated with signal $signal\n";
+       }
 
-    if (WIFSIGNALED ($status)) {
-       my ($signal) = WTERMSIG ($status);
-       die "Interrupted\n" if $signal == SIGINT;
-       print "Child terminated with signal $signal\n";
+       my ($exp_status) = !defined ($options{EXPECT}) ? 0 : $options{EXPECT};
+       $ok = WIFEXITED ($status) && WEXITSTATUS ($status) == $exp_status;
     }
 
-    unlink ("output/$log.err") if defined ($log) && $status == 0;
+    unlink ("output/$log.err") if defined ($log) && $ok;
 
-    die $options{DIE} if $status != 0 && defined $options{DIE};
+    die $options{DIE} if !$ok && defined $options{DIE};
 
-    return $status == 0;
+    return $ok;
 }
 
 sub snarf {