diff options
Diffstat (limited to 'src/runtime/crash_cgo_test.go')
-rw-r--r-- | src/runtime/crash_cgo_test.go | 68 |
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") +} +` |