]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: install sigPreempt signal handler for c-archive/c-shared
authorIan Lance Taylor <iant@golang.org>
Tue, 2 Nov 2021 21:12:05 +0000 (14:12 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 3 Nov 2021 00:49:50 +0000 (00:49 +0000)
Fixes #49288

Change-Id: I7bfcbecbefa68871a3e556935a73f241fff44c0e
Reviewed-on: https://go-review.googlesource.com/c/go/+/360861
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
misc/cgo/testcarchive/carchive_test.go
misc/cgo/testcarchive/testdata/libgo8/a.go [new file with mode: 0644]
misc/cgo/testcarchive/testdata/main8.c [new file with mode: 0644]
src/runtime/signal_unix.go

index 55be3c5f70710ffe3f1847ac9a545790cdf0d501..a2b43bb72d8d3a351d9c86f715d736d390f42bc5 100644 (file)
@@ -931,3 +931,55 @@ func TestManyCalls(t *testing.T) {
                t.Error(err)
        }
 }
+
+// Issue 49288.
+func TestPreemption(t *testing.T) {
+       if runtime.Compiler == "gccgo" {
+               t.Skip("skipping asynchronous preemption test with gccgo")
+       }
+
+       t.Parallel()
+
+       if !testWork {
+               defer func() {
+                       os.Remove("testp8" + exeSuffix)
+                       os.Remove("libgo8.a")
+                       os.Remove("libgo8.h")
+               }()
+       }
+
+       cmd := exec.Command("go", "build", "-buildmode=c-archive", "-o", "libgo8.a", "./libgo8")
+       if out, err := cmd.CombinedOutput(); err != nil {
+               t.Logf("%s", out)
+               t.Fatal(err)
+       }
+       checkLineComments(t, "libgo8.h")
+
+       ccArgs := append(cc, "-o", "testp8"+exeSuffix, "main8.c", "libgo8.a")
+       if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
+               t.Logf("%s", out)
+               t.Fatal(err)
+       }
+
+       argv := cmdToRun("./testp8")
+       cmd = exec.Command(argv[0], argv[1:]...)
+       var sb strings.Builder
+       cmd.Stdout = &sb
+       cmd.Stderr = &sb
+       if err := cmd.Start(); err != nil {
+               t.Fatal(err)
+       }
+
+       timer := time.AfterFunc(time.Minute,
+               func() {
+                       t.Error("test program timed out")
+                       cmd.Process.Kill()
+               },
+       )
+       defer timer.Stop()
+
+       if err := cmd.Wait(); err != nil {
+               t.Log(sb.String())
+               t.Error(err)
+       }
+}
diff --git a/misc/cgo/testcarchive/testdata/libgo8/a.go b/misc/cgo/testcarchive/testdata/libgo8/a.go
new file mode 100644 (file)
index 0000000..718418e
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2021 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.
+
+package main
+
+import "C"
+
+import (
+       "os"
+       "runtime"
+       "sync/atomic"
+)
+
+var started int32
+
+// Start a goroutine that loops forever.
+func init() {
+       runtime.GOMAXPROCS(1)
+       go func() {
+               for {
+                       atomic.StoreInt32(&started, 1)
+               }
+       }()
+}
+
+//export GoFunction8
+func GoFunction8() {
+       for atomic.LoadInt32(&started) == 0 {
+               runtime.Gosched()
+       }
+       os.Exit(0)
+}
+
+func main() {
+}
diff --git a/misc/cgo/testcarchive/testdata/main8.c b/misc/cgo/testcarchive/testdata/main8.c
new file mode 100644 (file)
index 0000000..95fb7a3
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2021 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.
+
+// Test preemption.
+
+#include <stdlib.h>
+
+#include "libgo8.h"
+
+int main() {
+       GoFunction8();
+
+       // That should have exited the program.
+       abort();
+}
index 7c454437e4dc300d35ff9f52229aeaf0f59da1fc..dbcbfc67bca3af97ba65e694faf66fd4b3941979 100644 (file)
@@ -167,8 +167,8 @@ func sigInstallGoHandler(sig uint32) bool {
        }
 
        // When built using c-archive or c-shared, only install signal
-       // handlers for synchronous signals and SIGPIPE.
-       if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE {
+       // handlers for synchronous signals and SIGPIPE and sigPreempt.
+       if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE && sig != sigPreempt {
                return false
        }