mirror of
https://github.com/golang/go
synced 2024-11-23 05:00:07 -07:00
runtime: if the test program hangs, try to get a stack trace
This is an attempt to get more information for #14809, which seems to occur rarely. Updates #14809. Change-Id: Idbeb136ceb57993644e03266622eb699d2685d02 Reviewed-on: https://go-review.googlesource.com/24110 Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
48cc3c4b58
commit
26d6dc6bf8
13
src/runtime/crash_nonunix_test.go
Normal file
13
src/runtime/crash_nonunix_test.go
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows plan9 nacl
|
||||
|
||||
package runtime_test
|
||||
|
||||
import "os"
|
||||
|
||||
// sigquit is the signal to send to kill a hanging testdata program.
|
||||
// On Unix we send SIGQUIT, but on non-Unix we only have os.Kill.
|
||||
var sigquit = os.Kill
|
@ -5,6 +5,7 @@
|
||||
package runtime_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
@ -13,9 +14,11 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var toRemove []string
|
||||
@ -65,8 +68,45 @@ func runTestProg(t *testing.T, binary, name string) string {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, _ := testEnv(exec.Command(exe, name)).CombinedOutput()
|
||||
return string(got)
|
||||
|
||||
cmd := testEnv(exec.Command(exe, name))
|
||||
var b bytes.Buffer
|
||||
cmd.Stdout = &b
|
||||
cmd.Stderr = &b
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatalf("starting %s %s: %v", binary, name, err)
|
||||
}
|
||||
|
||||
// If the process doesn't complete within 1 minute,
|
||||
// assume it is hanging and kill it to get a stack trace.
|
||||
p := cmd.Process
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
scale := 1
|
||||
// This GOARCH/GOOS test is copied from cmd/dist/test.go.
|
||||
// TODO(iant): Have cmd/dist update the environment variable.
|
||||
if runtime.GOARCH == "arm" || runtime.GOOS == "windows" {
|
||||
scale = 2
|
||||
}
|
||||
if s := os.Getenv("GO_TEST_TIMEOUT_SCALE"); s != "" {
|
||||
if sc, err := strconv.Atoi(s); err == nil {
|
||||
scale = sc
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(time.Duration(scale) * time.Minute):
|
||||
p.Signal(sigquit)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
t.Logf("%s %s exit status: %v", binary, name, err)
|
||||
}
|
||||
close(done)
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func buildTestProg(t *testing.T, binary string, flags ...string) (string, error) {
|
||||
|
@ -19,6 +19,10 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// sigquit is the signal to send to kill a hanging testdata program.
|
||||
// Send SIGQUIT to get a stack trace.
|
||||
var sigquit = syscall.SIGQUIT
|
||||
|
||||
func TestCrashDumpsAllThreads(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "darwin", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
|
||||
|
Loading…
Reference in New Issue
Block a user