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//go:build unix 6 7package main 8 9import ( 10 "fmt" 11 "os" 12) 13 14/* 15#include <signal.h> 16#include <stdlib.h> 17#include <stdio.h> 18#include <string.h> 19 20sig_atomic_t expectCSigsegv; 21int *sigfwdP; 22 23static void sigsegv() { 24 expectCSigsegv = 1; 25 *sigfwdP = 1; 26 fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n"); 27 exit(2); 28} 29 30static void segvhandler(int signum) { 31 if (signum == SIGSEGV) { 32 if (expectCSigsegv == 0) { 33 fprintf(stderr, "SIGSEGV caught in C unexpectedly\n"); 34 exit(1); 35 } 36 fprintf(stdout, "OK\n"); 37 exit(0); // success 38 } 39} 40 41static void __attribute__ ((constructor)) sigsetup(void) { 42 if (getenv("GO_TEST_CGOSIGFWD") == NULL) { 43 return; 44 } 45 46 struct sigaction act; 47 48 memset(&act, 0, sizeof act); 49 act.sa_handler = segvhandler; 50 sigaction(SIGSEGV, &act, NULL); 51} 52*/ 53import "C" 54 55func init() { 56 register("CgoSigfwd", CgoSigfwd) 57} 58 59var nilPtr *byte 60 61func f() (ret bool) { 62 defer func() { 63 if recover() == nil { 64 fmt.Fprintf(os.Stderr, "ERROR: couldn't raise SIGSEGV in Go\n") 65 C.exit(2) 66 } 67 ret = true 68 }() 69 *nilPtr = 1 70 return false 71} 72 73func CgoSigfwd() { 74 if os.Getenv("GO_TEST_CGOSIGFWD") == "" { 75 fmt.Fprintf(os.Stderr, "test must be run with GO_TEST_CGOSIGFWD set\n") 76 os.Exit(1) 77 } 78 79 // Test that the signal originating in Go is handled (and recovered) by Go. 80 if !f() { 81 fmt.Fprintf(os.Stderr, "couldn't recover from SIGSEGV in Go.\n") 82 C.exit(2) 83 } 84 85 // Test that the signal originating in C is handled by C. 86 C.sigsegv() 87} 88