Home | History | Annotate | Download | only in testsigfwd
      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 package main
      6 
      7 import "fmt"
      8 
      9 /*
     10 #cgo CFLAGS: -pthread
     11 #cgo LDFLAGS: -pthread
     12 
     13 #include <signal.h>
     14 #include <stdlib.h>
     15 #include <stdio.h>
     16 #include <string.h>
     17 #include <pthread.h>
     18 
     19 int *p;
     20 static void sigsegv() {
     21 	*p = 1;
     22 	fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n");
     23 	exit(2);
     24 }
     25 
     26 static void segvhandler(int signum) {
     27 	if (signum == SIGSEGV) {
     28 		exit(0);  // success
     29 	}
     30 }
     31 
     32 static volatile sig_atomic_t sigioSeen;
     33 
     34 // Use up some stack space.
     35 static void recur(int i, char *p) {
     36 	char a[1024];
     37 
     38 	*p = '\0';
     39 	if (i > 0) {
     40 		recur(i - 1, a);
     41 	}
     42 }
     43 
     44 static void iohandler(int signum) {
     45 	char a[1024];
     46 
     47 	recur(4, a);
     48 	sigioSeen = 1;
     49 }
     50 
     51 static void* sigioThread(void* arg __attribute__ ((unused))) {
     52 	raise(SIGIO);
     53 	return NULL;
     54 }
     55 
     56 static void sigioOnThread() {
     57 	pthread_t tid;
     58 	int i;
     59 
     60 	pthread_create(&tid, NULL, sigioThread, NULL);
     61 	pthread_join(tid, NULL);
     62 
     63 	// Wait until the signal has been delivered.
     64 	i = 0;
     65 	while (!sigioSeen) {
     66 		if (sched_yield() < 0) {
     67 			perror("sched_yield");
     68 		}
     69 		i++;
     70 		if (i > 10000) {
     71 			fprintf(stderr, "looping too long waiting for signal\n");
     72 			exit(EXIT_FAILURE);
     73 		}
     74 	}
     75 }
     76 
     77 static void __attribute__ ((constructor)) sigsetup(void) {
     78 	struct sigaction act;
     79 
     80 	memset(&act, 0, sizeof act);
     81 	act.sa_handler = segvhandler;
     82 	sigaction(SIGSEGV, &act, NULL);
     83 
     84 	act.sa_handler = iohandler;
     85 	sigaction(SIGIO, &act, NULL);
     86 }
     87 */
     88 import "C"
     89 
     90 var p *byte
     91 
     92 func f() (ret bool) {
     93 	defer func() {
     94 		if recover() == nil {
     95 			fmt.Errorf("ERROR: couldn't raise SIGSEGV in Go.")
     96 			C.exit(2)
     97 		}
     98 		ret = true
     99 	}()
    100 	*p = 1
    101 	return false
    102 }
    103 
    104 func main() {
    105 	// Test that the signal originating in Go is handled (and recovered) by Go.
    106 	if !f() {
    107 		fmt.Errorf("couldn't recover from SIGSEGV in Go.")
    108 		C.exit(2)
    109 	}
    110 
    111 	// Test that the signal originating in C is handled by C.
    112 	C.sigsegv()
    113 }
    114