github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/misc/cgo/testsanitizers/tsan11.go (about)

     1  // Copyright 2017 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  package main
     6  
     7  // This program hung when run under the C/C++ ThreadSanitizer. TSAN defers
     8  // asynchronous signals until the signaled thread calls into libc. The runtime's
     9  // sysmon goroutine idles itself using direct usleep syscalls, so it could
    10  // run for an arbitrarily long time without triggering the libc interceptors.
    11  // See https://golang.org/issue/18717.
    12  
    13  import (
    14  	"os"
    15  	"os/signal"
    16  	"syscall"
    17  )
    18  
    19  /*
    20  #cgo CFLAGS: -g -fsanitize=thread
    21  #cgo LDFLAGS: -g -fsanitize=thread
    22  
    23  #include <signal.h>
    24  #include <stdio.h>
    25  #include <stdlib.h>
    26  #include <string.h>
    27  
    28  static void raise_usr2(int signo) {
    29  	raise(SIGUSR2);
    30  }
    31  
    32  static void register_handler(int signo) {
    33  	struct sigaction sa;
    34  	memset(&sa, 0, sizeof(sa));
    35  	sigemptyset(&sa.sa_mask);
    36  	sa.sa_flags = SA_ONSTACK;
    37  	sa.sa_handler = raise_usr2;
    38  
    39  	if (sigaction(SIGUSR1, &sa, NULL) != 0) {
    40  		perror("failed to register SIGUSR1 handler");
    41  		exit(EXIT_FAILURE);
    42  	}
    43  }
    44  */
    45  import "C"
    46  
    47  func main() {
    48  	ch := make(chan os.Signal)
    49  	signal.Notify(ch, syscall.SIGUSR2)
    50  
    51  	C.register_handler(C.int(syscall.SIGUSR1))
    52  	syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
    53  
    54  	<-ch
    55  }