Home | History | Annotate | Download | only in src
      1 // Copyright 2016 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 failed when run under the C/C++ ThreadSanitizer.  The TSAN
      8 // sigaction function interceptor returned SIG_DFL instead of the Go runtime's
      9 // handler in registerSegvForwarder.
     10 
     11 /*
     12 #cgo CFLAGS: -fsanitize=thread
     13 #cgo LDFLAGS: -fsanitize=thread
     14 
     15 #include <signal.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 
     20 struct sigaction prev_sa;
     21 
     22 void forwardSignal(int signo, siginfo_t *info, void *context) {
     23 	// One of sa_sigaction and/or sa_handler
     24 	if ((prev_sa.sa_flags&SA_SIGINFO) != 0) {
     25 		prev_sa.sa_sigaction(signo, info, context);
     26 		return;
     27 	}
     28 	if (prev_sa.sa_handler != SIG_IGN && prev_sa.sa_handler != SIG_DFL) {
     29 		prev_sa.sa_handler(signo);
     30 		return;
     31 	}
     32 
     33 	fprintf(stderr, "No Go handler to forward to!\n");
     34 	abort();
     35 }
     36 
     37 void registerSegvFowarder() {
     38 	struct sigaction sa;
     39 	memset(&sa, 0, sizeof(sa));
     40 	sigemptyset(&sa.sa_mask);
     41 	sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
     42 	sa.sa_sigaction = forwardSignal;
     43 
     44 	if (sigaction(SIGSEGV, &sa, &prev_sa) != 0) {
     45 		perror("failed to register SEGV forwarder");
     46 		exit(EXIT_FAILURE);
     47 	}
     48 }
     49 */
     50 import "C"
     51 
     52 func main() {
     53 	C.registerSegvFowarder()
     54 
     55 	defer func() {
     56 		recover()
     57 	}()
     58 	var nilp *int
     59 	*nilp = 42
     60 }
     61