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 failed with SIGSEGV when run under the C/C++ ThreadSanitizer. 8 // The Go runtime had re-registered the C handler with the wrong flags due to a 9 // typo, resulting in null pointers being passed for the info and context 10 // parameters to the handler. 11 12 /* 13 #cgo CFLAGS: -fsanitize=thread 14 #cgo LDFLAGS: -fsanitize=thread 15 16 #include <signal.h> 17 #include <stdio.h> 18 #include <stdlib.h> 19 #include <string.h> 20 #include <ucontext.h> 21 22 void check_params(int signo, siginfo_t *info, void *context) { 23 ucontext_t* uc = (ucontext_t*)(context); 24 25 if (info->si_signo != signo) { 26 fprintf(stderr, "info->si_signo does not match signo.\n"); 27 abort(); 28 } 29 30 if (uc->uc_stack.ss_size == 0) { 31 fprintf(stderr, "uc_stack has size 0.\n"); 32 abort(); 33 } 34 } 35 36 37 // Set up the signal handler in a high priority constructor, so 38 // that it is installed before the Go code starts. 39 40 static void register_handler(void) __attribute__ ((constructor (200))); 41 42 static void register_handler() { 43 struct sigaction sa; 44 memset(&sa, 0, sizeof(sa)); 45 sigemptyset(&sa.sa_mask); 46 sa.sa_flags = SA_SIGINFO; 47 sa.sa_sigaction = check_params; 48 49 if (sigaction(SIGUSR1, &sa, NULL) != 0) { 50 perror("failed to register SIGUSR1 handler"); 51 exit(EXIT_FAILURE); 52 } 53 } 54 */ 55 import "C" 56 57 import "syscall" 58 59 func init() { 60 C.raise(C.int(syscall.SIGUSR1)) 61 } 62 63 func main() {} 64