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