Home | History | Annotate | Download | only in src
      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 }
     56