Skip to content

Commit 4122319

Browse files
author
Elias Naur
committed
misc/ios: forward SIGQUIT to the iOS program
When running tests that fails to complete within the test timeout, the go tool sends the test program a SIGQUIT signal to print backtraces. However, for tests running with an exec wrapper, the resulting backtraces will come from the exec wrapper process and not the test program. Change the iOS exec wrapper to forward SIGQUIT signals to the lldb python driver and change the driver to forward the signals to the running test on the device. Before: $ GOARCH=arm64 go test forever_test.go lldb: running program SIGQUIT: quit PC=0x10816fe m=0 sigcode=0 goroutine 54 [syscall]: syscall.Syscall6(0x7, 0x16ab, 0xc000033dfc, 0x0, 0xc000116f30, 0x0, 0x0, 0xc000116f30, 0x0, 0x1328820) /Users/elias/go-tip/src/syscall/asm_darwin_amd64.s:41 +0x5 fp=0xc000033d48 sp=0xc000033d40 pc=0x10816d5 syscall.wait4(0x16ab, 0xc000033dfc, 0x0, 0xc000116f30, 0x90, 0x1200e00, 0x1) /Users/elias/go-tip/src/syscall/zsyscall_darwin_amd64.go:34 +0x7b fp=0xc000033dc0 sp=0xc000033d48 pc=0x107e4eb syscall.Wait4(0x16ab, 0xc000033e4c, 0x0, 0xc000116f30, 0xc0000fd518, 0x0, 0x0) /Users/elias/go-tip/src/syscall/syscall_bsd.go:129 +0x51 fp=0xc000033e10 sp=0xc000033dc0 pc=0x107b7b1 os.(*Process).wait(0xc00008d440, 0x1095e2e, 0xc0000fd518, 0x0) /Users/elias/go-tip/src/os/exec_unix.go:38 +0x7b fp=0xc000033e80 sp=0xc000033e10 pc=0x109af2b os.(*Process).Wait(0xc00008d440, 0xc000033fb0, 0x10, 0x11d1f00) /Users/elias/go-tip/src/os/exec.go:125 +0x2b fp=0xc000033eb0 sp=0xc000033e80 pc=0x109a47b os/exec.(*Cmd).Wait(0xc0000b1ce0, 0xc000033f90, 0x11394df) /Users/elias/go-tip/src/os/exec/exec.go:463 +0x5b fp=0xc000033f28 sp=0xc000033eb0 pc=0x1136f0b main.startDebugBridge.func1(0xc0000b1ce0, 0xc0000b8ae0, 0xc0000e2a80) /Users/elias/go-tip/misc/ios/go_darwin_arm_exec.go:314 +0x40 fp=0xc000033fc8 sp=0xc000033f28 pc=0x11a1980 runtime.goexit() /Users/elias/go-tip/src/runtime/asm_amd64.s:1360 +0x1 fp=0xc000033fd0 sp=0xc000033fc8 pc=0x10565a1 created by main.startDebugBridge /Users/elias/go-tip/misc/ios/go_darwin_arm_exec.go:313 +0x15f ... After: $ GOARCH=arm64 go test forever_test.go lldb: running program === RUN TestForever SIGQUIT: quit PC=0x100144e24 m=0 sigcode=0 ... goroutine 19 [select (no cases)]: command-line-arguments.TestForever(0x1300b60f0) /Users/elias/go-tip/src/forever_test.go:6 +0x18 testing.tRunner(0x1300b60f0, 0x100211aa0) /Users/elias/go-tip/src/testing/testing.go:795 +0xa8 created by testing.(*T).Run /Users/elias/go-tip/src/testing/testing.go:840 +0x22c ... Change-Id: I6b3cf1662d07a43ade0530842733b0944bee1ace Reviewed-on: https://go-review.googlesource.com/112676 Run-TryBot: Elias Naur <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Hyang-Ah Hana Kim <[email protected]>
1 parent d89ea41 commit 4122319

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

misc/ios/go_darwin_arm_exec.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"net"
3232
"os"
3333
"os/exec"
34+
"os/signal"
3435
"path/filepath"
3536
"runtime"
3637
"strings"
@@ -498,7 +499,22 @@ func run(appdir, bundleID string, args []string) error {
498499
lldb.Stdout = os.Stdout
499500
var out bytes.Buffer
500501
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
501-
err = lldb.Run()
502+
err = lldb.Start()
503+
if err == nil {
504+
// Forward SIGQUIT to the lldb driver which in turn will forward
505+
// to the running program.
506+
sigs := make(chan os.Signal, 1)
507+
signal.Notify(sigs, syscall.SIGQUIT)
508+
proc := lldb.Process
509+
go func() {
510+
for sig := range sigs {
511+
proc.Signal(sig)
512+
}
513+
}()
514+
err = lldb.Wait()
515+
signal.Stop(sigs)
516+
close(sigs)
517+
}
502518
// If the program was not started it can be retried without papering over
503519
// real test failures.
504520
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
@@ -709,6 +725,7 @@ const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
709725
const lldbDriver = `
710726
import sys
711727
import os
728+
import signal
712729
713730
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
714731
@@ -747,6 +764,7 @@ for i in range(0, sigs.GetNumSignals()):
747764
748765
event = lldb.SBEvent()
749766
running = False
767+
prev_handler = None
750768
while True:
751769
if not listener.WaitForEvent(1, event):
752770
continue
@@ -766,6 +784,8 @@ while True:
766784
sys.stderr.write(out)
767785
state = process.GetStateFromEvent(event)
768786
if state in [lldb.eStateCrashed, lldb.eStateDetached, lldb.eStateUnloaded, lldb.eStateExited]:
787+
if running:
788+
signal.signal(signal.SIGQUIT, prev_handler)
769789
break
770790
elif state == lldb.eStateConnected:
771791
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
@@ -774,6 +794,10 @@ while True:
774794
process.Kill()
775795
debugger.Terminate()
776796
sys.exit(1)
797+
# Forward SIGQUIT to the program.
798+
def signal_handler(signal, frame):
799+
process.Signal(signal)
800+
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
777801
# Tell the Go driver that the program is running and should not be retried.
778802
sys.stderr.write("lldb: running program\n")
779803
running = True

0 commit comments

Comments
 (0)