github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/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  	"testing"
    11  )
    12  
    13  func TestCgoCrashHandler(t *testing.T) {
    14  	testCrashHandler(t, true)
    15  }
    16  
    17  func TestCgoSignalDeadlock(t *testing.T) {
    18  	got := executeTest(t, cgoSignalDeadlockSource, nil)
    19  	want := "OK\n"
    20  	if got != want {
    21  		t.Fatalf("expected %q, but got %q", want, got)
    22  	}
    23  }
    24  
    25  const cgoSignalDeadlockSource = `
    26  package main
    27  
    28  import "C"
    29  
    30  import (
    31  	"fmt"
    32  	"runtime"
    33  	"time"
    34  )
    35  
    36  func main() {
    37  	runtime.GOMAXPROCS(100)
    38  	ping := make(chan bool)
    39  	go func() {
    40  		for i := 0; ; i++ {
    41  			runtime.Gosched()
    42  			select {
    43  			case done := <-ping:
    44  				if done {
    45  					ping <- true
    46  					return
    47  				}
    48  				ping <- true
    49  			default:
    50  			}
    51  			func() {
    52  				defer func() {
    53  					recover()
    54  				}()
    55  				var s *string
    56  				*s = ""
    57  			}()
    58  		}
    59  	}()
    60  	time.Sleep(time.Millisecond)
    61  	for i := 0; i < 64; i++ {
    62  		go func() {
    63  			runtime.LockOSThread()
    64  			select {}
    65  		}()
    66  		go func() {
    67  			runtime.LockOSThread()
    68  			select {}
    69  		}()
    70  		time.Sleep(time.Millisecond)
    71  		ping <- false
    72  		select {
    73  		case <-ping:
    74  		case <-time.After(time.Second):
    75  			fmt.Printf("HANG\n")
    76  			return
    77  		}
    78  	}
    79  	ping <- true
    80  	select {
    81  	case <-ping:
    82  	case <-time.After(time.Second):
    83  		fmt.Printf("HANG\n")
    84  		return
    85  	}
    86  	fmt.Printf("OK\n")
    87  }
    88  `