aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/crash_cgo_test.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-10-03 16:58:34 -0700
committerIan Lance Taylor <iant@golang.org>2016-10-05 13:21:49 +0000
commit6c13a1db2ebe146fec7cc7261146ca0e8420f011 (patch)
treed21e8c18e33299acc7d99d5df1976358bb5b4493 /src/runtime/crash_cgo_test.go
parent7faf70239670c3c1f8b4b530aba8847a03860f2a (diff)
downloadgo-6c13a1db2ebe146fec7cc7261146ca0e8420f011.tar.gz
go-6c13a1db2ebe146fec7cc7261146ca0e8420f011.zip
runtime: don't call cgocallback from signal handler
Calling cgocallback from a signal handler can fail when using the race detector. Calling cgocallback will lead to a call to newextram which will call oneNewExtraM which will call racegostart. The racegostart function will set up some race detector data structures, and doing that will sometimes call the C memory allocator. If we are running the signal handler from a signal that interrupted the C memory allocator, we will crash or hang. Instead, change the signal handler code to call needm and dropm. The needm function will grab allocated m and g structures and initialize the g to use the current stack--the signal stack. That is all we need to safely call code that allocates memory and checks whether it needs to split the stack. This may temporarily leave us with no m available to run a cgo callback, but that is OK in this case since the code we call will quickly either crash or call dropm to return the m. Implementing this required changing some of the setSignalstackSP functions to avoid a write barrier. These functions never need a write barrier but in some cases generated one anyhow because on some systems the ss_sp field is a pointer. Change-Id: I3893f47c3a66278f85eab7f94c1ab11d4f3be133 Reviewed-on: https://go-review.googlesource.com/30218 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/crash_cgo_test.go')
-rw-r--r--src/runtime/crash_cgo_test.go29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 1e509c113a..2e2f95e5f0 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -319,3 +319,32 @@ func TestRaceProf(t *testing.T) {
t.Errorf("expected %q got %s", want, got)
}
}
+
+func TestRaceSignal(t *testing.T) {
+ if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
+ t.Skipf("not yet supported on %s/%s", runtime.GOOS, runtime.GOARCH)
+ }
+
+ testenv.MustHaveGoRun(t)
+
+ // This test requires building various packages with -race, so
+ // it's somewhat slow.
+ if testing.Short() {
+ t.Skip("skipping test in -short mode")
+ }
+
+ exe, err := buildTestProg(t, "testprogcgo", "-race")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ got, err := testEnv(exec.Command(exe, "CgoRaceSignal")).CombinedOutput()
+ if err != nil {
+ t.Logf("%s\n", got)
+ t.Fatal(err)
+ }
+ want := "OK\n"
+ if string(got) != want {
+ t.Errorf("expected %q got %s", want, got)
+ }
+}