aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Turner <andrew@fubar.geek.nz>2019-10-21 13:25:55 +0100
committerMichael Tüxen <tuexen@fh-muenster.de>2019-10-21 14:25:55 +0200
commitb24d2b8a213c09b511478e7eab5fa343e4a198de (patch)
treee5c1c459fedf77172e3f28ed935ded9a2391e675
parent8c88c9c1c99c8cd8dabc951164c820b9c9f25114 (diff)
vm: Get debug information when FreeBSD on panics (#1470)
The FreeBSD kernel debugger can provide more information when the kernel panics. Add support to bhybe and gce to print this information.
-rw-r--r--vm/bhyve/bhyve.go17
-rw-r--r--vm/gce/gce.go3
-rw-r--r--vm/vmimpl/freebsd.go32
3 files changed, 51 insertions, 1 deletions
diff --git a/vm/bhyve/bhyve.go b/vm/bhyve/bhyve.go
index 36177dac6..0000e2c27 100644
--- a/vm/bhyve/bhyve.go
+++ b/vm/bhyve/bhyve.go
@@ -49,6 +49,7 @@ type instance struct {
merger *vmimpl.OutputMerger
vmName string
bhyve *exec.Cmd
+ consolew io.WriteCloser
}
var ipRegex = regexp.MustCompile(`bound to (([0-9]+\.){3}[0-9]+) `)
@@ -177,17 +178,28 @@ func (inst *instance) Boot() error {
if err != nil {
return err
}
+ inr, inw, err := osutil.LongPipe()
+ if err != nil {
+ outr.Close()
+ outw.Close()
+ return err
+ }
bhyve := osutil.Command("bhyve", bhyveArgs...)
+ bhyve.Stdin = inr
bhyve.Stdout = outw
bhyve.Stderr = outw
if err := bhyve.Start(); err != nil {
outr.Close()
outw.Close()
+ inr.Close()
+ inw.Close()
return err
}
outw.Close()
outw = nil
+ inst.consolew = inw
+ inr.Close()
inst.bhyve = bhyve
var tee io.Writer
@@ -245,6 +257,9 @@ func (inst *instance) Boot() error {
}
func (inst *instance) Close() {
+ if inst.consolew != nil {
+ inst.consolew.Close()
+ }
if inst.bhyve != nil {
inst.bhyve.Process.Kill()
inst.bhyve.Wait()
@@ -331,7 +346,7 @@ func (inst *instance) Run(timeout time.Duration, stop <-chan bool, command strin
}
func (inst *instance) Diagnose() ([]byte, bool) {
- return nil, false
+ return nil, vmimpl.DiagnoseFreeBSD(inst.consolew)
}
func parseIP(output []byte) string {
diff --git a/vm/gce/gce.go b/vm/gce/gce.go
index cad34addf..98ab494dd 100644
--- a/vm/gce/gce.go
+++ b/vm/gce/gce.go
@@ -370,6 +370,9 @@ func waitForConsoleConnect(merger *vmimpl.OutputMerger) error {
}
func (inst *instance) Diagnose() ([]byte, bool) {
+ if inst.env.OS == "freebsd" {
+ return nil, vmimpl.DiagnoseFreeBSD(inst.consolew)
+ }
if inst.env.OS == "openbsd" {
return nil, vmimpl.DiagnoseOpenBSD(inst.consolew)
}
diff --git a/vm/vmimpl/freebsd.go b/vm/vmimpl/freebsd.go
new file mode 100644
index 000000000..c6074028a
--- /dev/null
+++ b/vm/vmimpl/freebsd.go
@@ -0,0 +1,32 @@
+// Copyright 2018 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package vmimpl
+
+import (
+ "io"
+ "time"
+)
+
+// DiagnoseFreeBSD sends the debug commands to the given writer which
+// is expected to be connected to a panicked FreeBSD kernel. If kernel
+// just hanged, we've lost connection or detected some non-panic
+// error, console still shows normal login prompt.
+func DiagnoseFreeBSD(w io.Writer) bool {
+ commands := []string{
+ "",
+ "set $lines = 0", // disable pagination
+ "set $maxwidth = 0", // disable line continuation
+ "show registers",
+ "show proc",
+ "ps",
+ "show all locks",
+ "show malloc",
+ "show ktr",
+ }
+ for _, c := range commands {
+ w.Write([]byte(c + "\n"))
+ time.Sleep(1 * time.Second)
+ }
+ return true
+}