mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-27 13:20:34 +00:00
vm: properly detect when a program exits
syz-fuzzer never exits (normally) so this does not affect syz-manager. But during reproduction we can run a short running program (no repeat mode) and currently VMs treat premature exit as an error. Properly detect when a program exits and let callers decide what to do with it.
This commit is contained in:
parent
b9371a6101
commit
3558653771
@ -379,9 +379,16 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
|
||||
}
|
||||
signal(fmt.Errorf("instance closed"))
|
||||
case err := <-merger.Err:
|
||||
adb.Process.Kill()
|
||||
merger.Wait()
|
||||
if cmdErr := adb.Wait(); cmdErr == nil {
|
||||
// If the command exited successfully, we got EOF error from merger.
|
||||
// But in this case no error has happened and the EOF is expected.
|
||||
err = nil
|
||||
}
|
||||
signal(err)
|
||||
return
|
||||
}
|
||||
tty.Close()
|
||||
adb.Process.Kill()
|
||||
merger.Wait()
|
||||
adb.Wait()
|
||||
|
@ -214,13 +214,24 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
|
||||
case <-inst.closed:
|
||||
signal(fmt.Errorf("instance closed"))
|
||||
case err := <-merger.Err:
|
||||
// Check if the instance was terminated due to preemption or host maintenance.
|
||||
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
|
||||
con.Process.Kill()
|
||||
ssh.Process.Kill()
|
||||
merger.Wait()
|
||||
con.Wait()
|
||||
if cmdErr := ssh.Wait(); cmdErr == nil {
|
||||
// If the command exited successfully, we got EOF error from merger.
|
||||
// But in this case no error has happened and the EOF is expected.
|
||||
err = nil
|
||||
} else {
|
||||
// Check if the instance was terminated due to preemption or host maintenance.
|
||||
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
|
||||
}
|
||||
}
|
||||
signal(err)
|
||||
return
|
||||
}
|
||||
con.Process.Kill()
|
||||
ssh.Process.Kill()
|
||||
|
@ -354,7 +354,14 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
|
||||
case <-stop:
|
||||
signal(vm.TimeoutErr)
|
||||
case err := <-inst.merger.Err:
|
||||
cmd.Process.Kill()
|
||||
if cmdErr := cmd.Wait(); cmdErr == nil {
|
||||
// If the command exited successfully, we got EOF error from merger.
|
||||
// But in this case no error has happened and the EOF is expected.
|
||||
err = nil
|
||||
}
|
||||
signal(err)
|
||||
return
|
||||
}
|
||||
cmd.Process.Kill()
|
||||
cmd.Wait()
|
||||
|
9
vm/vm.go
9
vm/vm.go
@ -119,7 +119,7 @@ func MonitorExecution(outc <-chan []byte, errc <-chan error, local, needOutput b
|
||||
return "preempted", nil, nil, false, true
|
||||
}
|
||||
if !report.ContainsCrash(output[matchPos:], ignores) {
|
||||
return defaultError, nil, output, true, false
|
||||
return defaultError, nil, output, defaultError != "", false
|
||||
}
|
||||
desc, text, start, end := report.Parse(output[matchPos:], ignores)
|
||||
start = start + matchPos - beforeContext
|
||||
@ -146,8 +146,9 @@ func MonitorExecution(outc <-chan []byte, errc <-chan error, local, needOutput b
|
||||
case err := <-errc:
|
||||
switch err {
|
||||
case nil:
|
||||
waitForOutput()
|
||||
return "", nil, output, false, false
|
||||
// The program has exited without errors,
|
||||
// but wait for kernel output in case there is some delayed oops.
|
||||
return extractError("")
|
||||
case TimeoutErr:
|
||||
return err.Error(), nil, nil, false, true
|
||||
default:
|
||||
@ -164,7 +165,7 @@ func MonitorExecution(outc <-chan []byte, errc <-chan error, local, needOutput b
|
||||
lastExecuteTime = time.Now()
|
||||
}
|
||||
if report.ContainsCrash(output[matchPos:], ignores) {
|
||||
return extractError("")
|
||||
return extractError("unknown error")
|
||||
}
|
||||
if len(output) > 2*beforeContext {
|
||||
copy(output, output[len(output)-beforeContext:])
|
||||
|
Loading…
Reference in New Issue
Block a user