Commit f6fea0f3 authored by Austin Clements's avatar Austin Clements

runtime: skip debug call injection tests under a debugger

The debug call injection tests will freeze when run under a debugger
because they depend on catching SIGTRAP, which is usually swallowed by
a debugger.

Change-Id: If6b86ca279b0489182990dd513444ca3062973f1
Reviewed-on: https://go-review.googlesource.com/c/139437
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent 112f28de
...@@ -17,6 +17,8 @@ package runtime_test ...@@ -17,6 +17,8 @@ package runtime_test
import ( import (
"fmt" "fmt"
"io/ioutil"
"regexp"
"runtime" "runtime"
"runtime/debug" "runtime/debug"
"sync/atomic" "sync/atomic"
...@@ -25,6 +27,11 @@ import ( ...@@ -25,6 +27,11 @@ import (
) )
func startDebugCallWorker(t *testing.T) (g *runtime.G, after func()) { func startDebugCallWorker(t *testing.T) (g *runtime.G, after func()) {
// This can deadlock if run under a debugger because it
// depends on catching SIGTRAP, which is usually swallowed by
// a debugger.
skipUnderDebugger(t)
// This can deadlock if there aren't enough threads or if a GC // This can deadlock if there aren't enough threads or if a GC
// tries to interrupt an atomic loop (see issue #10958). // tries to interrupt an atomic loop (see issue #10958).
ogomaxprocs := runtime.GOMAXPROCS(2) ogomaxprocs := runtime.GOMAXPROCS(2)
...@@ -73,6 +80,28 @@ func debugCallTKill(tid int) error { ...@@ -73,6 +80,28 @@ func debugCallTKill(tid int) error {
return syscall.Tgkill(syscall.Getpid(), tid, syscall.SIGTRAP) return syscall.Tgkill(syscall.Getpid(), tid, syscall.SIGTRAP)
} }
// skipUnderDebugger skips the current test when running under a
// debugger (specifically if this process has a tracer). This is
// Linux-specific.
func skipUnderDebugger(t *testing.T) {
pid := syscall.Getpid()
status, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/status", pid))
if err != nil {
t.Logf("couldn't get proc tracer: %s", err)
return
}
re := regexp.MustCompile(`TracerPid:\s+([0-9]+)`)
sub := re.FindSubmatch(status)
if sub == nil {
t.Logf("couldn't find proc tracer PID")
return
}
if string(sub[1]) == "0" {
return
}
t.Skip("test will deadlock under a debugger")
}
func TestDebugCall(t *testing.T) { func TestDebugCall(t *testing.T) {
g, after := startDebugCallWorker(t) g, after := startDebugCallWorker(t)
defer after() defer after()
...@@ -160,6 +189,8 @@ func debugCallUnsafePointWorker(gpp **runtime.G, ready, stop *uint32) { ...@@ -160,6 +189,8 @@ func debugCallUnsafePointWorker(gpp **runtime.G, ready, stop *uint32) {
} }
func TestDebugCallUnsafePoint(t *testing.T) { func TestDebugCallUnsafePoint(t *testing.T) {
skipUnderDebugger(t)
// This can deadlock if there aren't enough threads or if a GC // This can deadlock if there aren't enough threads or if a GC
// tries to interrupt an atomic loop (see issue #10958). // tries to interrupt an atomic loop (see issue #10958).
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
...@@ -181,6 +212,8 @@ func TestDebugCallUnsafePoint(t *testing.T) { ...@@ -181,6 +212,8 @@ func TestDebugCallUnsafePoint(t *testing.T) {
} }
func TestDebugCallPanic(t *testing.T) { func TestDebugCallPanic(t *testing.T) {
skipUnderDebugger(t)
// This can deadlock if there aren't enough threads. // This can deadlock if there aren't enough threads.
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
......
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