if t.hasBash() && goos != "android" && !t.iOS() && gohostos != "windows" {
t.registerHostTest("cgo_errors", "../misc/cgo/errors", "misc/cgo/errors", ".")
}
- if gohostos == "linux" && t.extLink() {
- t.registerTest("testsigfwd", "../misc/cgo/testsigfwd", "go", "run", ".")
- }
}
if goos != "android" && !t.iOS() {
import (
"fmt"
+ "internal/goos"
"internal/testenv"
"os"
"os/exec"
t.Fatalf("GOMAXPROCS=1, want %s, got %s\n", want, output)
}
}
+
+func TestCgoSigfwd(t *testing.T) {
+ t.Parallel()
+ if goos.IsLinux == 0 {
+ t.Skipf("only supported on Linux")
+ }
+
+ got := runTestProg(t, "testprogcgo", "CgoSigfwd", "GO_TEST_CGOSIGFWD=1")
+ if want := "OK\n"; got != want {
+ t.Fatalf("expected %q, but got:\n%s", want, got)
+ }
+}
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
+//go:build linux
+
package main
-import "fmt"
+import (
+ "fmt"
+ "os"
+)
/*
#include <signal.h>
#include <stdio.h>
#include <string.h>
-int *p;
+int *sigfwdP;
static void sigsegv() {
- *p = 1;
+ *sigfwdP = 1;
fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n");
exit(2);
}
static void segvhandler(int signum) {
if (signum == SIGSEGV) {
- fprintf(stdout, "ok\ttestsigfwd\n");
+ fprintf(stdout, "OK\n");
exit(0); // success
}
}
static void __attribute__ ((constructor)) sigsetup(void) {
+ if (getenv("GO_TEST_CGOSIGFWD") == NULL) {
+ return;
+ }
+
struct sigaction act;
memset(&act, 0, sizeof act);
*/
import "C"
-var p *byte
+func init() {
+ register("CgoSigfwd", CgoSigfwd)
+}
+
+var nilPtr *byte
func f() (ret bool) {
defer func() {
}
ret = true
}()
- *p = 1
+ *nilPtr = 1
return false
}
-func main() {
+func CgoSigfwd() {
+ if os.Getenv("GO_TEST_CGOSIGFWD") == "" {
+ fmt.Fprintf(os.Stderr, "test must be run with GO_TEST_CGOSIGFWD set\n")
+ os.Exit(1)
+ }
+
// Test that the signal originating in Go is handled (and recovered) by Go.
if !f() {
- fmt.Errorf("couldn't recover from SIGSEGV in Go.")
+ fmt.Fprintf(os.Stderr, "couldn't recover from SIGSEGV in Go.\n")
C.exit(2)
}