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