]> Cypherpunks repositories - gostls13.git/commitdiff
misc/android: don't let the Android exec wrapper hang indefinitely
authorElias Naur <elias.naur@gmail.com>
Mon, 1 May 2017 18:35:08 +0000 (20:35 +0200)
committerElias Naur <elias.naur@gmail.com>
Mon, 1 May 2017 22:31:15 +0000 (22:31 +0000)
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 <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
misc/android/go_android_exec.go

index ebff8451548529fe590b4e420c1415df25942b45..49b7ae902c3837be2c893797d4a04419a27f9ad0 100644 (file)
@@ -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 {