• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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