github.com/riscv/riscv-go@v0.0.0-20200123204226-124ebd6fcc8e/misc/cgo/test/sigaltstack.go (about) 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 // +build !windows,!android 6 7 // Test that the Go runtime still works if C code changes the signal stack. 8 9 package cgotest 10 11 /* 12 #include <signal.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 17 static stack_t oss; 18 static char signalStack[SIGSTKSZ]; 19 20 static void changeSignalStack(void) { 21 stack_t ss; 22 memset(&ss, 0, sizeof ss); 23 ss.ss_sp = signalStack; 24 ss.ss_flags = 0; 25 ss.ss_size = SIGSTKSZ; 26 if (sigaltstack(&ss, &oss) < 0) { 27 perror("sigaltstack"); 28 abort(); 29 } 30 } 31 32 static void restoreSignalStack(void) { 33 #if (defined(__x86_64__) || defined(__i386__)) && defined(__APPLE__) 34 // The Darwin C library enforces a minimum that the kernel does not. 35 // This is OK since we allocated this much space in mpreinit, 36 // it was just removed from the buffer by stackalloc. 37 oss.ss_size = MINSIGSTKSZ; 38 #endif 39 if (sigaltstack(&oss, NULL) < 0) { 40 perror("sigaltstack restore"); 41 abort(); 42 } 43 } 44 45 static int zero(void) { 46 return 0; 47 } 48 */ 49 import "C" 50 51 import ( 52 "runtime" 53 "testing" 54 ) 55 56 func testSigaltstack(t *testing.T) { 57 switch { 58 case runtime.GOOS == "solaris", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"): 59 t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 60 case runtime.GOOS == "darwin" && runtime.GOARCH == "386": 61 t.Skipf("sigaltstack fails on darwin/386") 62 } 63 64 C.changeSignalStack() 65 defer C.restoreSignalStack() 66 defer func() { 67 if recover() == nil { 68 t.Error("did not see expected panic") 69 } 70 }() 71 v := 1 / int(C.zero()) 72 t.Errorf("unexpected success of division by zero == %d", v) 73 }