1 // Copyright 2012 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
16 func TestCgoCrashHandler(t
*testing
.T
) {
17 testCrashHandler(t
, true)
20 func TestCgoSignalDeadlock(t
*testing
.T
) {
21 if testing
.Short() && runtime
.GOOS
== "windows" {
22 t
.Skip("Skipping in short mode") // takes up to 64 seconds
24 got
:= executeTest(t
, cgoSignalDeadlockSource
, nil)
27 t
.Fatalf("expected %q, but got %q", want
, got
)
31 func TestCgoTraceback(t
*testing
.T
) {
32 got
:= executeTest(t
, cgoTracebackSource
, nil)
35 t
.Fatalf("expected %q, but got %q", want
, got
)
39 func TestCgoExternalThreadPanic(t
*testing
.T
) {
40 if runtime
.GOOS
== "plan9" {
41 t
.Skipf("no pthreads on %s", runtime
.GOOS
)
43 csrc
:= cgoExternalThreadPanicC
44 if runtime
.GOOS
== "windows" {
45 csrc
= cgoExternalThreadPanicC_windows
47 got
:= executeTest(t
, cgoExternalThreadPanicSource
, nil, "main.c", csrc
)
49 if !strings
.Contains(got
, want
) {
50 t
.Fatalf("want failure containing %q. output:\n%s\n", want
, got
)
54 func TestCgoExternalThreadSIGPROF(t
*testing
.T
) {
57 case "plan9", "windows":
58 t
.Skipf("no pthreads on %s", runtime
.GOOS
)
60 // static constructor needs external linking, but we don't support
61 // external linking on OS X 10.6.
62 out
, err
:= exec
.Command("uname", "-r").Output()
64 t
.Fatalf("uname -r failed: %v", err
)
66 // OS X 10.6 == Darwin 10.x
67 if strings
.HasPrefix(string(out
), "10.") {
68 t
.Skipf("no external linking on OS X 10.6")
71 got
:= executeTest(t
, cgoExternalThreadSIGPROFSource
, nil)
74 t
.Fatalf("expected %q, but got %q", want
, got
)
78 const cgoSignalDeadlockSource
= `
90 runtime.GOMAXPROCS(100)
91 ping := make(chan bool)
113 time.Sleep(time.Millisecond)
114 for i := 0; i < 64; i++ {
116 runtime.LockOSThread()
120 runtime.LockOSThread()
123 time.Sleep(time.Millisecond)
127 case <-time.After(time.Second):
135 case <-time.After(time.Second):
143 const cgoTracebackSource
= `
146 /* void foo(void) {} */
156 buf := make([]byte, 1)
157 runtime.Stack(buf, true)
162 const cgoExternalThreadPanicSource
= `
179 const cgoExternalThreadPanicC
= `
197 if(pthread_create(&t, 0, die, 0) != 0)
198 printf("pthread_create failed\n");
202 const cgoExternalThreadPanicC_windows
= `
218 if(_beginthreadex(0, 0, die, 0, 0, 0) != 0)
219 printf("_beginthreadex failed\n");
223 const cgoExternalThreadSIGPROFSource
= `
231 volatile int32_t spinlock;
233 static void *thread1(void *p) {
235 while (spinlock == 0)
237 pthread_kill(pthread_self(), SIGPROF);
241 __attribute__((constructor)) void issue9456() {
243 pthread_create(&tid, 0, thread1, NULL);
255 // This test intends to test that sending SIGPROF to foreign threads
256 // before we make any cgo call will not abort the whole process, so
257 // we cannot make any cgo call here. See http://golang.org/issue/9456.
258 atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1)
259 for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 {