aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-06-20 15:35:45 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-06-22 16:40:45 +0200
commitd3bbcc35ee486a3d456fe58fa0600fc93b7a79fe (patch)
tree53f56f5eb5ab1f30f7df489addeba3a8d9273c94
parent9a7d0a5412c35bdc7d0ec09fc21c1d4277e62d31 (diff)
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.
-rw-r--r--vm/adb/adb.go4
-rw-r--r--vm/gce/gce.go4
-rw-r--r--vm/isolated/isolated.go4
-rw-r--r--vm/kvm/kvm.go4
-rw-r--r--vm/qemu/qemu.go4
-rw-r--r--vm/vm.go10
-rw-r--r--vm/vmimpl/vmimpl.go5
7 files changed, 35 insertions, 0 deletions
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()
}