Commit 7ba1c91d authored by Elias Naur's avatar Elias Naur

misc/android: forward SIGQUIT to the process running on the device

When a test binary runs for too long, the go command sends it a
SIGQUIT to force a backtrace dump. On Android, the exec wrapper
will instead receive the signal and dump its backtrace.

Forward SIGQUIT signals from the wrapper to the wrapped process
to gain useful backtraces.

Inspired by issuse 25519; this CL would have revealed the hanging
test directly in the builder log.

Change-Id: Ic362d06940d261374343a1dc09366ef54edaa631
Reviewed-on: https://go-review.googlesource.com/114137
Run-TryBot: Elias Naur <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 77c51c6c
...@@ -14,10 +14,12 @@ import ( ...@@ -14,10 +14,12 @@ import (
"log" "log"
"os" "os"
"os/exec" "os/exec"
"os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"syscall"
) )
func run(args ...string) string { func run(args ...string) string {
...@@ -73,8 +75,8 @@ func main() { ...@@ -73,8 +75,8 @@ func main() {
// Binary names can conflict. // Binary names can conflict.
// E.g. template.test from the {html,text}/template packages. // E.g. template.test from the {html,text}/template packages.
binName := filepath.Base(os.Args[1]) binName := fmt.Sprintf("%s-%d", filepath.Base(os.Args[1]), os.Getpid())
deviceBin := fmt.Sprintf("%s/%s-%d", deviceGotmp, binName, os.Getpid()) deviceBin := fmt.Sprintf("%s/%s", deviceGotmp, binName)
// The push of the binary happens in parallel with other tests. // The push of the binary happens in parallel with other tests.
// Unfortunately, a simultaneous call to adb shell hold open // Unfortunately, a simultaneous call to adb shell hold open
...@@ -85,6 +87,17 @@ func main() { ...@@ -85,6 +87,17 @@ func main() {
run("shell", "cp '"+deviceBin+"-tmp' '"+deviceBin+"'") run("shell", "cp '"+deviceBin+"-tmp' '"+deviceBin+"'")
run("shell", "rm '"+deviceBin+"-tmp'") run("shell", "rm '"+deviceBin+"-tmp'")
// Forward SIGQUIT from the go command to show backtraces from
// the binary instead of from this wrapper.
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGQUIT)
go func() {
for range quit {
// We don't have the PID of the running process; use the
// binary name instead.
run("shell", "killall -QUIT "+binName)
}
}()
// The adb shell command will return an exit code of 0 regardless // The adb shell command will return an exit code of 0 regardless
// of the command run. E.g. // of the command run. E.g.
// $ adb shell false // $ adb shell false
...@@ -100,6 +113,8 @@ func main() { ...@@ -100,6 +113,8 @@ func main() {
"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") + "; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
"; echo -n " + exitstr + "$?" "; echo -n " + exitstr + "$?"
output := run("shell", cmd) output := run("shell", cmd)
signal.Reset(syscall.SIGQUIT)
close(quit)
run("shell", "rm", "-rf", deviceGotmp) // Clean up. run("shell", "rm", "-rf", deviceGotmp) // Clean up.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment