| // Copyright 2015 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // +build !windows,!android | |
| // Test that the Go runtime still works if C code changes the signal stack. | |
| package cgotest | |
| /* | |
| #include <signal.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| static stack_t oss; | |
| static char signalStack[SIGSTKSZ]; | |
| static void changeSignalStack(void) { | |
| stack_t ss; | |
| memset(&ss, 0, sizeof ss); | |
| ss.ss_sp = signalStack; | |
| ss.ss_flags = 0; | |
| ss.ss_size = SIGSTKSZ; | |
| if (sigaltstack(&ss, &oss) < 0) { | |
| perror("sigaltstack"); | |
| abort(); | |
| } | |
| } | |
| static void restoreSignalStack(void) { | |
| #if (defined(__x86_64__) || defined(__i386__)) && defined(__APPLE__) | |
| // The Darwin C library enforces a minimum that the kernel does not. | |
| // This is OK since we allocated this much space in mpreinit, | |
| // it was just removed from the buffer by stackalloc. | |
| oss.ss_size = MINSIGSTKSZ; | |
| #endif | |
| if (sigaltstack(&oss, NULL) < 0) { | |
| perror("sigaltstack restore"); | |
| abort(); | |
| } | |
| } | |
| static int zero(void) { | |
| return 0; | |
| } | |
| */ | |
| import "C" | |
| import ( | |
| "runtime" | |
| "testing" | |
| ) | |
| func testSigaltstack(t *testing.T) { | |
| switch { | |
| case runtime.GOOS == "solaris", runtime.GOOS == "illumos", runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64"): | |
| t.Skipf("switching signal stack not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) | |
| case runtime.GOOS == "darwin" && runtime.GOARCH == "386": | |
| t.Skipf("sigaltstack fails on darwin/386") | |
| } | |
| C.changeSignalStack() | |
| defer C.restoreSignalStack() | |
| defer func() { | |
| if recover() == nil { | |
| t.Error("did not see expected panic") | |
| } | |
| }() | |
| v := 1 / int(C.zero()) | |
| t.Errorf("unexpected success of division by zero == %d", v) | |
| } |