diff --git a/qemu/qemu-kernel.go b/qemu/qemu-kernel.go index 0a7de1d..cee5f1c 100644 --- a/qemu/qemu-kernel.go +++ b/qemu/qemu-kernel.go @@ -67,6 +67,9 @@ type QemuSystem struct { Cpus int Memory int + debug bool + gdb string // tcp::1234 + // Timeout works after Start invocation Timeout time.Duration KilledByTimeout bool @@ -184,6 +187,10 @@ func (q *QemuSystem) Start() (err error) { "-netdev", "user,id=n1," + hostfwd, } + if q.debug { + qemuArgs = append(qemuArgs, "-gdb", q.gdb) + } + if q.kernel.InitrdPath != "" { qemuArgs = append(qemuArgs, "-initrd", q.kernel.InitrdPath) } @@ -338,3 +345,8 @@ func (q *QemuSystem) CopyAndRun(user, path string) (output string, err error) { return q.Command(user, "chmod +x "+remotePath+" && "+remotePath) } + +func (q *QemuSystem) Debug(conn string) { + q.debug = true + q.gdb = conn +} diff --git a/qemu/qemu-kernel_test.go b/qemu/qemu-kernel_test.go index 048001c..21fd4d2 100644 --- a/qemu/qemu-kernel_test.go +++ b/qemu/qemu-kernel_test.go @@ -299,3 +299,47 @@ func TestQemuSystemRun(t *testing.T) { } } + +func openedPort(port int) bool { + conn, err := net.Dial("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + return false + } + conn.Close() + return true +} + +func TestQemuSystemDebug(t *testing.T) { + t.Parallel() + kernel := Kernel{ + KernelPath: testConfigVmlinuz, + InitrdPath: testConfigInitrd, + } + q, err := NewQemuSystem(X86_64, kernel, testConfigRootfs) + if err != nil { + return + } + + port := 45256 + + q.Debug(fmt.Sprintf("tcp::%d", port)) + + if openedPort(port) { + t.Fatal("Port opened before qemu starts") + } + + if err = q.Start(); err != nil { + return + } + defer q.Stop() + + if !openedPort(port) { + t.Fatal("Qemu debug port does not opened") + } + + q.Stop() + + if openedPort(port) { + t.Fatal("Qemu listens after die") + } +}