vm/gce: handle graceful preemption

In case of graceful preemption fuzzer should be terminated by SIGTERM.
Catch it and propagate to manager.
This commit is contained in:
Dmitry Vyukov 2016-12-16 16:11:18 +01:00
parent f83633edbe
commit a59452c4b2
4 changed files with 15 additions and 2 deletions

View File

@ -16,6 +16,7 @@ import (
"net/rpc"
"net/rpc/jsonrpc"
"os"
"os/signal"
"runtime/debug"
"strconv"
"strings"
@ -98,6 +99,15 @@ func main() {
}
Logf(0, "fuzzer started")
go func() {
// Handles graceful preemption on GCE.
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
<-c
Logf(0, "SYZ-FUZZER: PREEMPTED")
os.Exit(1)
}()
corpusCover = make([]cover.Cover, sys.CallCount)
maxCover = make([]cover.Cover, sys.CallCount)
corpusHashes = make(map[Sig]struct{})

View File

@ -384,7 +384,7 @@ func (mgr *Manager) runInstance(vmCfg *vm.Config, first bool) (*Crash, error) {
desc, text, output, crashed, timedout := vm.MonitorExecution(outc, errc, mgr.cfg.Type == "local", true)
if timedout {
// This is the only "OK" outcome.
Logf(0, "%v: running for %v, restarting", vmCfg.Name, time.Since(start))
Logf(0, "%v: running for %v, restarting (%v)", vmCfg.Name, time.Since(start), desc)
return nil, nil
}
if !crashed {

View File

@ -234,7 +234,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
ssh.Process.Kill()
case err := <-sshDone:
// Check if the instance was terminated due to preemption or host maintenance.
time.Sleep(time.Second) // just to avoid any GCE races
time.Sleep(5 * time.Second) // just to avoid any GCE races
if !GCE.IsInstanceRunning(inst.name) {
Logf(1, "%v: ssh exited but instance is not running", inst.name)
err = vm.TimeoutErr

View File

@ -114,6 +114,9 @@ func MonitorExecution(outc <-chan []byte, errc <-chan error, local, needOutput b
extractError := func(defaultError string) (string, []byte, []byte, bool, bool) {
// Give it some time to finish writing the error message.
waitForOutput()
if bytes.Contains(output, []byte("SYZ-FUZZER: PREEMPTED")) {
return "preempted", nil, nil, false, true
}
if !report.ContainsCrash(output[matchPos:]) {
return defaultError, nil, output, true, false
}