github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/src/runtime/crash_cgo_test.go (about)

     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.
     4  
     5  // +build cgo
     6  
     7  package runtime_test
     8  
     9  import (
    10  	"runtime"
    11  	"strings"
    12  	"testing"
    13  )
    14  
    15  func TestCgoCrashHandler(t *testing.T) {
    16  	testCrashHandler(t, true)
    17  }
    18  
    19  func TestCgoSignalDeadlock(t *testing.T) {
    20  	if testing.Short() && runtime.GOOS == "windows" {
    21  		t.Skip("Skipping in short mode") // takes up to 64 seconds
    22  	}
    23  	got := executeTest(t, cgoSignalDeadlockSource, nil)
    24  	want := "OK\n"
    25  	if got != want {
    26  		t.Fatalf("expected %q, but got %q", want, got)
    27  	}
    28  }
    29  
    30  func TestCgoTraceback(t *testing.T) {
    31  	got := executeTest(t, cgoTracebackSource, nil)
    32  	want := "OK\n"
    33  	if got != want {
    34  		t.Fatalf("expected %q, but got %q", want, got)
    35  	}
    36  }
    37  
    38  func TestCgoExternalThreadPanic(t *testing.T) {
    39  	if runtime.GOOS == "plan9" {
    40  		t.Skipf("no pthreads on %s", runtime.GOOS)
    41  	}
    42  	csrc := cgoExternalThreadPanicC
    43  	if runtime.GOOS == "windows" {
    44  		csrc = cgoExternalThreadPanicC_windows
    45  	}
    46  	got := executeTest(t, cgoExternalThreadPanicSource, nil, "main.c", csrc)
    47  	want := "panic: BOOM"
    48  	if !strings.Contains(got, want) {
    49  		t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
    50  	}
    51  }
    52  
    53  const cgoSignalDeadlockSource = `
    54  package main
    55  
    56  import "C"
    57  
    58  import (
    59  	"fmt"
    60  	"runtime"
    61  	"time"
    62  )
    63  
    64  func main() {
    65  	runtime.GOMAXPROCS(100)
    66  	ping := make(chan bool)
    67  	go func() {
    68  		for i := 0; ; i++ {
    69  			runtime.Gosched()
    70  			select {
    71  			case done := <-ping:
    72  				if done {
    73  					ping <- true
    74  					return
    75  				}
    76  				ping <- true
    77  			default:
    78  			}
    79  			func() {
    80  				defer func() {
    81  					recover()
    82  				}()
    83  				var s *string
    84  				*s = ""
    85  			}()
    86  		}
    87  	}()
    88  	time.Sleep(time.Millisecond)
    89  	for i := 0; i < 64; i++ {
    90  		go func() {
    91  			runtime.LockOSThread()
    92  			select {}
    93  		}()
    94  		go func() {
    95  			runtime.LockOSThread()
    96  			select {}
    97  		}()
    98  		time.Sleep(time.Millisecond)
    99  		ping <- false
   100  		select {
   101  		case <-ping:
   102  		case <-time.After(time.Second):
   103  			fmt.Printf("HANG\n")
   104  			return
   105  		}
   106  	}
   107  	ping <- true
   108  	select {
   109  	case <-ping:
   110  	case <-time.After(time.Second):
   111  		fmt.Printf("HANG\n")
   112  		return
   113  	}
   114  	fmt.Printf("OK\n")
   115  }
   116  `
   117  
   118  const cgoTracebackSource = `
   119  package main
   120  
   121  /* void foo(void) {} */
   122  import "C"
   123  
   124  import (
   125  	"fmt"
   126  	"runtime"
   127  )
   128  
   129  func main() {
   130  	C.foo()
   131  	buf := make([]byte, 1)
   132  	runtime.Stack(buf, true)
   133  	fmt.Printf("OK\n")
   134  }
   135  `
   136  
   137  const cgoExternalThreadPanicSource = `
   138  package main
   139  
   140  // void start(void);
   141  import "C"
   142  
   143  func main() {
   144  	C.start()
   145  	select {}
   146  }
   147  
   148  //export gopanic
   149  func gopanic() {
   150  	panic("BOOM")
   151  }
   152  `
   153  
   154  const cgoExternalThreadPanicC = `
   155  #include <stdlib.h>
   156  #include <stdio.h>
   157  #include <pthread.h>
   158  
   159  void gopanic(void);
   160  
   161  static void*
   162  die(void* x)
   163  {
   164  	gopanic();
   165  	return 0;
   166  }
   167  
   168  void
   169  start(void)
   170  {
   171  	pthread_t t;
   172  	if(pthread_create(&t, 0, die, 0) != 0)
   173  		printf("pthread_create failed\n");
   174  }
   175  `
   176  
   177  const cgoExternalThreadPanicC_windows = `
   178  #include <stdlib.h>
   179  #include <stdio.h>
   180  
   181  void gopanic(void);
   182  
   183  static void*
   184  die(void* x)
   185  {
   186  	gopanic();
   187  	return 0;
   188  }
   189  
   190  void
   191  start(void)
   192  {
   193  	if(_beginthreadex(0, 0, die, 0, 0, 0) != 0)
   194  		printf("_beginthreadex failed\n");
   195  }
   196  `