Source file src/runtime/testdata/testprogcgo/sigfwd.go

     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  
     7  package main
     8  
     9  import (
    10  	"fmt"
    11  	"os"
    12  )
    13  
    14  /*
    15  #include <signal.h>
    16  #include <stdlib.h>
    17  #include <stdio.h>
    18  #include <string.h>
    19  
    20  sig_atomic_t expectCSigsegv;
    21  int *sigfwdP;
    22  
    23  static void sigsegv() {
    24  	expectCSigsegv = 1;
    25  	*sigfwdP = 1;
    26  	fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n");
    27  	exit(2);
    28  }
    29  
    30  static 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  
    41  static 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  */
    53  import "C"
    54  
    55  func init() {
    56  	register("CgoSigfwd", CgoSigfwd)
    57  }
    58  
    59  var nilPtr *byte
    60  
    61  func 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  
    73  func 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  

View as plain text