libgo: Upgrade to Go 1.4.2 release.
[official-gcc.git] / libgo / go / runtime / crash_cgo_test.go
blob29f90fa36d27fc521c008ad71b923b103334bd52
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.
5 // +build cgo
7 package runtime_test
9 import (
10 "os/exec"
11 "runtime"
12 "strings"
13 "testing"
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)
25 want := "OK\n"
26 if got != want {
27 t.Fatalf("expected %q, but got %q", want, got)
31 func TestCgoTraceback(t *testing.T) {
32 got := executeTest(t, cgoTracebackSource, nil)
33 want := "OK\n"
34 if got != want {
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)
48 want := "panic: BOOM"
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) {
55 // issue 9456.
56 switch runtime.GOOS {
57 case "plan9", "windows":
58 t.Skipf("no pthreads on %s", runtime.GOOS)
59 case "darwin":
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()
63 if err != nil {
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)
72 want := "OK\n"
73 if got != want {
74 t.Fatalf("expected %q, but got %q", want, got)
78 const cgoSignalDeadlockSource = `
79 package main
81 import "C"
83 import (
84 "fmt"
85 "runtime"
86 "time"
89 func main() {
90 runtime.GOMAXPROCS(100)
91 ping := make(chan bool)
92 go func() {
93 for i := 0; ; i++ {
94 runtime.Gosched()
95 select {
96 case done := <-ping:
97 if done {
98 ping <- true
99 return
101 ping <- true
102 default:
104 func() {
105 defer func() {
106 recover()
108 var s *string
109 *s = ""
113 time.Sleep(time.Millisecond)
114 for i := 0; i < 64; i++ {
115 go func() {
116 runtime.LockOSThread()
117 select {}
119 go func() {
120 runtime.LockOSThread()
121 select {}
123 time.Sleep(time.Millisecond)
124 ping <- false
125 select {
126 case <-ping:
127 case <-time.After(time.Second):
128 fmt.Printf("HANG\n")
129 return
132 ping <- true
133 select {
134 case <-ping:
135 case <-time.After(time.Second):
136 fmt.Printf("HANG\n")
137 return
139 fmt.Printf("OK\n")
143 const cgoTracebackSource = `
144 package main
146 /* void foo(void) {} */
147 import "C"
149 import (
150 "fmt"
151 "runtime"
154 func main() {
155 C.foo()
156 buf := make([]byte, 1)
157 runtime.Stack(buf, true)
158 fmt.Printf("OK\n")
162 const cgoExternalThreadPanicSource = `
163 package main
165 // void start(void);
166 import "C"
168 func main() {
169 C.start()
170 select {}
173 //export gopanic
174 func gopanic() {
175 panic("BOOM")
179 const cgoExternalThreadPanicC = `
180 #include <stdlib.h>
181 #include <stdio.h>
182 #include <pthread.h>
184 void gopanic(void);
186 static void*
187 die(void* x)
189 gopanic();
190 return 0;
193 void
194 start(void)
196 pthread_t t;
197 if(pthread_create(&t, 0, die, 0) != 0)
198 printf("pthread_create failed\n");
202 const cgoExternalThreadPanicC_windows = `
203 #include <stdlib.h>
204 #include <stdio.h>
206 void gopanic(void);
208 static void*
209 die(void* x)
211 gopanic();
212 return 0;
215 void
216 start(void)
218 if(_beginthreadex(0, 0, die, 0, 0, 0) != 0)
219 printf("_beginthreadex failed\n");
223 const cgoExternalThreadSIGPROFSource = `
224 package main
227 #include <stdint.h>
228 #include <signal.h>
229 #include <pthread.h>
231 volatile int32_t spinlock;
233 static void *thread1(void *p) {
234 (void)p;
235 while (spinlock == 0)
237 pthread_kill(pthread_self(), SIGPROF);
238 spinlock = 0;
239 return NULL;
241 __attribute__((constructor)) void issue9456() {
242 pthread_t tid;
243 pthread_create(&tid, 0, thread1, NULL);
246 import "C"
248 import (
249 "runtime"
250 "sync/atomic"
251 "unsafe"
254 func main() {
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 {
260 runtime.Gosched()
262 println("OK")