summaryrefslogtreecommitdiff
path: root/src/runtime/crash_cgo_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/crash_cgo_test.go')
-rw-r--r--src/runtime/crash_cgo_test.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index 972eedc62..29f90fa36 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -7,6 +7,7 @@
package runtime_test
import (
+ "os/exec"
"runtime"
"strings"
"testing"
@@ -50,6 +51,30 @@ func TestCgoExternalThreadPanic(t *testing.T) {
}
}
+func TestCgoExternalThreadSIGPROF(t *testing.T) {
+ // issue 9456.
+ switch runtime.GOOS {
+ case "plan9", "windows":
+ t.Skipf("no pthreads on %s", runtime.GOOS)
+ case "darwin":
+ // static constructor needs external linking, but we don't support
+ // external linking on OS X 10.6.
+ out, err := exec.Command("uname", "-r").Output()
+ if err != nil {
+ t.Fatalf("uname -r failed: %v", err)
+ }
+ // OS X 10.6 == Darwin 10.x
+ if strings.HasPrefix(string(out), "10.") {
+ t.Skipf("no external linking on OS X 10.6")
+ }
+ }
+ got := executeTest(t, cgoExternalThreadSIGPROFSource, nil)
+ want := "OK\n"
+ if got != want {
+ t.Fatalf("expected %q, but got %q", want, got)
+ }
+}
+
const cgoSignalDeadlockSource = `
package main
@@ -194,3 +219,46 @@ start(void)
printf("_beginthreadex failed\n");
}
`
+
+const cgoExternalThreadSIGPROFSource = `
+package main
+
+/*
+#include <stdint.h>
+#include <signal.h>
+#include <pthread.h>
+
+volatile int32_t spinlock;
+
+static void *thread1(void *p) {
+ (void)p;
+ while (spinlock == 0)
+ ;
+ pthread_kill(pthread_self(), SIGPROF);
+ spinlock = 0;
+ return NULL;
+}
+__attribute__((constructor)) void issue9456() {
+ pthread_t tid;
+ pthread_create(&tid, 0, thread1, NULL);
+}
+*/
+import "C"
+
+import (
+ "runtime"
+ "sync/atomic"
+ "unsafe"
+)
+
+func main() {
+ // This test intends to test that sending SIGPROF to foreign threads
+ // before we make any cgo call will not abort the whole process, so
+ // we cannot make any cgo call here. See http://golang.org/issue/9456.
+ atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1)
+ for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 {
+ runtime.Gosched()
+ }
+ println("OK")
+}
+`