From d3bbcc35ee486a3d456fe58fa0600fc93b7a79fe Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 20 Jun 2018 15:35:45 +0200 Subject: vm/vmimpl: add vm.Diagnose method Diagnose is called on machine hang to try to get some additional diagnostic information from it. For now it's all stubs. --- vm/adb/adb.go | 4 ++++ vm/gce/gce.go | 4 ++++ vm/isolated/isolated.go | 4 ++++ vm/kvm/kvm.go | 4 ++++ vm/qemu/qemu.go | 4 ++++ vm/vm.go | 10 ++++++++++ vm/vmimpl/vmimpl.go | 5 +++++ 7 files changed, 35 insertions(+) (limited to 'vm') diff --git a/vm/adb/adb.go b/vm/adb/adb.go index 3b839ea00..91bef1e0f 100644 --- a/vm/adb/adb.go +++ b/vm/adb/adb.go @@ -428,3 +428,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin return vmimpl.Multiplex(adb, merger, tty, timeout, stop, inst.closed, inst.debug) } + +func (inst *instance) Diagnose() bool { + return false +} diff --git a/vm/gce/gce.go b/vm/gce/gce.go index dbd1001fd..b715c4afb 100644 --- a/vm/gce/gce.go +++ b/vm/gce/gce.go @@ -350,6 +350,10 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin return merger.Output, errc, nil } +func (inst *instance) Diagnose() bool { + return false +} + func (pool *Pool) waitInstanceBoot(name, ip, sshKey, sshUser, gceKey string) error { pwd := "pwd" if pool.env.OS == "windows" { diff --git a/vm/isolated/isolated.go b/vm/isolated/isolated.go index f86ec96fd..6c79f7cd6 100644 --- a/vm/isolated/isolated.go +++ b/vm/isolated/isolated.go @@ -308,6 +308,10 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin return vmimpl.Multiplex(cmd, merger, dmesg, timeout, stop, inst.closed, inst.debug) } +func (inst *instance) Diagnose() bool { + return false +} + func (inst *instance) sshArgs(portArg string) []string { args := []string{ portArg, fmt.Sprint(inst.targetPort), diff --git a/vm/kvm/kvm.go b/vm/kvm/kvm.go index 7911936e3..68604ae98 100644 --- a/vm/kvm/kvm.go +++ b/vm/kvm/kvm.go @@ -285,6 +285,10 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin return outputC, errorC, nil } +func (inst *instance) Diagnose() bool { + return false +} + const script = `#! /bin/bash while true; do if [ -e "/syz-cmd" ]; then diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go index 135f11235..189d3e13c 100644 --- a/vm/qemu/qemu.go +++ b/vm/qemu/qemu.go @@ -487,6 +487,10 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin return inst.merger.Output, errc, nil } +func (inst *instance) Diagnose() bool { + return false +} + func (inst *instance) sshArgs(portArg string) []string { args := []string{ portArg, strconv.Itoa(inst.port), diff --git a/vm/vm.go b/vm/vm.go index ff283cd2f..7082011dd 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -97,6 +97,10 @@ func (inst *Instance) Run(timeout time.Duration, stop <-chan bool, command strin return inst.impl.Run(timeout, stop, command) } +func (inst *Instance) Diagnose() bool { + return inst.impl.Diagnose() +} + func (inst *Instance) Close() { inst.impl.Close() os.RemoveAll(inst.workdir) @@ -217,6 +221,9 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, // We intentionally produce the same title as no output at all, // because frequently it's the same condition. if time.Since(lastExecuteTime) > 3*time.Minute { + if inst.Diagnose() { + waitForOutput() + } rep := &report.Report{ Title: "no output from test machine", Output: output, @@ -225,6 +232,9 @@ func (inst *Instance) MonitorExecution(outc <-chan []byte, errc <-chan error, } case <-ticker.C: tickerFired = true + if inst.Diagnose() { + waitForOutput() + } rep := &report.Report{ Title: "no output from test machine", Output: output, diff --git a/vm/vmimpl/vmimpl.go b/vm/vmimpl/vmimpl.go index 532611abd..7d3411ee9 100644 --- a/vm/vmimpl/vmimpl.go +++ b/vm/vmimpl/vmimpl.go @@ -43,6 +43,11 @@ type Instance interface { // Command is terminated after timeout. Send on the stop chan can be used to terminate it earlier. Run(timeout time.Duration, stop <-chan bool, command string) (outc <-chan []byte, errc <-chan error, err error) + // Diagnose forces VM to dump additional debugging info + // (e.g. sending some sys-rq's or SIGABORT'ing a Go program). + // Returns true if it did anything. + Diagnose() bool + // Close stops and destroys the VM. Close() } -- cgit mrf-deployment