From: Elias Naur Date: Mon, 1 May 2017 18:35:08 +0000 (+0200) Subject: misc/android: don't let the Android exec wrapper hang indefinitely X-Git-Tag: go1.9beta1~360 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=00f827784b37babedcd7da53cdd5d657eb761dd3;p=gostls13.git misc/android: don't let the Android exec wrapper hang indefinitely On Android, the exec wrapper passes on output from adb to its parent process by passing on os.Stderr and os.Stdout to adb. If the adb process somehow hangs, it will keep stderr and stdout will open, in turn blocking go test from ever returning from its cmd.Wait() even though it has killed the exec wrapper process. Break the short circuit by introducing a wrapper between adb and the exec wrapper, preventing os/exec.Run from passing along the raw file descriptors for os.Stdout and os.Stderr. (Hopefully) fixes occasional indefinite hangs on the Android builder. Change-Id: I1188211fbde79b4a66bf93ff8e9d0091abf34560 Reviewed-on: https://go-review.googlesource.com/42271 Run-TryBot: Elias Naur TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/misc/android/go_android_exec.go b/misc/android/go_android_exec.go index ebff845154..49b7ae902c 100644 --- a/misc/android/go_android_exec.go +++ b/misc/android/go_android_exec.go @@ -24,7 +24,16 @@ func run(args ...string) string { buf := new(bytes.Buffer) cmd := exec.Command("adb", args...) cmd.Stdout = io.MultiWriter(os.Stdout, buf) - cmd.Stderr = os.Stderr + // If the adb subprocess somehow hangs, go test will kill this wrapper + // and wait for our os.Stderr (and os.Stdout) to close as a result. + // However, if the os.Stderr (or os.Stdout) file descriptors are + // passed on, the hanging adb subprocess will hold them open and + // go test will hang forever. + // + // Avoid that by wrapping stderr, breaking the short circuit and + // forcing cmd.Run to use another pipe and goroutine to pass + // along stderr from adb. + cmd.Stderr = struct{ io.Writer }{os.Stderr} log.Printf("adb %s", strings.Join(args, " ")) err := cmd.Run() if err != nil {