github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/testdata/testprogcgo/threadprof.go (about) 1 // Copyright 2015 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 !plan9,!windows 6 7 package main 8 9 /* 10 #include <stdint.h> 11 #include <signal.h> 12 #include <pthread.h> 13 14 volatile int32_t spinlock; 15 16 static void *thread1(void *p) { 17 (void)p; 18 while (spinlock == 0) 19 ; 20 pthread_kill(pthread_self(), SIGPROF); 21 spinlock = 0; 22 return NULL; 23 } 24 __attribute__((constructor)) void issue9456() { 25 pthread_t tid; 26 pthread_create(&tid, 0, thread1, NULL); 27 } 28 29 void **nullptr; 30 31 void *crash(void *p) { 32 *nullptr = p; 33 return 0; 34 } 35 36 int start_crashing_thread(void) { 37 pthread_t tid; 38 return pthread_create(&tid, 0, crash, 0); 39 } 40 */ 41 import "C" 42 43 import ( 44 "fmt" 45 "os" 46 "os/exec" 47 "runtime" 48 "sync/atomic" 49 "time" 50 "unsafe" 51 ) 52 53 func init() { 54 register("CgoExternalThreadSIGPROF", CgoExternalThreadSIGPROF) 55 register("CgoExternalThreadSignal", CgoExternalThreadSignal) 56 } 57 58 func CgoExternalThreadSIGPROF() { 59 // This test intends to test that sending SIGPROF to foreign threads 60 // before we make any cgo call will not abort the whole process, so 61 // we cannot make any cgo call here. See https://golang.org/issue/9456. 62 atomic.StoreInt32((*int32)(unsafe.Pointer(&C.spinlock)), 1) 63 for atomic.LoadInt32((*int32)(unsafe.Pointer(&C.spinlock))) == 1 { 64 runtime.Gosched() 65 } 66 println("OK") 67 } 68 69 func CgoExternalThreadSignal() { 70 if len(os.Args) > 2 && os.Args[2] == "crash" { 71 i := C.start_crashing_thread() 72 if i != 0 { 73 fmt.Println("pthread_create failed:", i) 74 // Exit with 0 because parent expects us to crash. 75 return 76 } 77 78 // We should crash immediately, but give it plenty of 79 // time before failing (by exiting 0) in case we are 80 // running on a slow system. 81 time.Sleep(5 * time.Second) 82 return 83 } 84 85 out, err := exec.Command(os.Args[0], "CgoExternalThreadSignal", "crash").CombinedOutput() 86 if err == nil { 87 fmt.Println("C signal did not crash as expected\n") 88 fmt.Printf("%s\n", out) 89 os.Exit(1) 90 } 91 92 fmt.Println("OK") 93 }