--- /dev/null
+// Copyright 2020 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 !arm64 !internal
+
+package cgotest
+
+import (
+ "runtime"
+ "runtime/debug"
+ "strings"
+ "sync/atomic"
+ "testing"
+)
+
+/*
+#include <stdint.h>
+
+void issue7978cb(void);
+
+// use ugly atomic variable sync since that doesn't require calling back into
+// Go code or OS dependencies
+static void issue7978c(uint32_t *sync) {
+ while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
+ ;
+ __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+ while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
+ ;
+ issue7978cb();
+ __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
+ while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
+ ;
+}
+
+*/
+import "C"
+
+// issue 7978
+
+var issue7978sync uint32
+
+func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
+ runtime.GC()
+ buf := make([]byte, 65536)
+ trace := string(buf[:runtime.Stack(buf, true)])
+ for _, goroutine := range strings.Split(trace, "\n\n") {
+ if strings.Contains(goroutine, "test.issue7978go") {
+ trace := strings.Split(goroutine, "\n")
+ // look for the expected function in the stack
+ for i := 0; i < depth; i++ {
+ if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
+ t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
+ return
+ }
+ if strings.Contains(trace[1+2*i], wantFunc) {
+ return
+ }
+ }
+ t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
+ return
+ }
+ }
+ t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
+}
+
+func issue7978wait(store uint32, wait uint32) {
+ if store != 0 {
+ atomic.StoreUint32(&issue7978sync, store)
+ }
+ for atomic.LoadUint32(&issue7978sync) != wait {
+ runtime.Gosched()
+ }
+}
+
+//export issue7978cb
+func issue7978cb() {
+ // Force a stack growth from the callback to put extra
+ // pressure on the runtime. See issue #17785.
+ growStack(64)
+ issue7978wait(3, 4)
+}
+
+func growStack(n int) int {
+ var buf [128]int
+ if n == 0 {
+ return 0
+ }
+ return buf[growStack(n-1)]
+}
+
+func issue7978go() {
+ C.issue7978c((*C.uint32_t)(&issue7978sync))
+ issue7978wait(7, 8)
+}
+
+func test7978(t *testing.T) {
+ if runtime.Compiler == "gccgo" {
+ t.Skip("gccgo can not do stack traces of C code")
+ }
+ debug.SetTraceback("2")
+ issue7978sync = 0
+ go issue7978go()
+ // test in c code, before callback
+ issue7978wait(0, 1)
+ issue7978check(t, "_Cfunc_issue7978c(", "", 1)
+ // test in go code, during callback
+ issue7978wait(2, 3)
+ issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
+ // test in c code, after callback
+ issue7978wait(4, 5)
+ issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
+ // test in go code, after return from cgo
+ issue7978wait(6, 7)
+ issue7978check(t, "test.issue7978go(", "", 3)
+ atomic.StoreUint32(&issue7978sync, 8)
+}
--- /dev/null
+// Copyright 2020 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.
+
+// GCC-9.4 and above on arm64 introduced the "outline atomics" that the
+// current internal linking doesn't support.
+// See issue #39466.
+
+// +build arm64,internal
+
+package cgotest
+
+import (
+ "runtime"
+ "testing"
+)
+
+func test7978(t *testing.T) {
+ if runtime.Compiler == "gccgo" {
+ t.Skip("gccgo can not do stack traces of C code")
+ }
+
+ t.Skip("skip on arm64+internal")
+}
import (
"runtime"
- "runtime/debug"
- "strings"
"sync"
- "sync/atomic"
"testing"
"time"
"unsafe"
extern void f7665(void);
-// issue 7978
-// Stack tracing didn't work during cgo code after calling a Go
-// callback. Make sure GC works and the stack trace is correct.
-
-#include <stdint.h>
-
-void issue7978cb(void);
-
-// use ugly atomic variable sync since that doesn't require calling back into
-// Go code or OS dependencies
-static void issue7978c(uint32_t *sync) {
- while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 0)
- ;
- __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
- while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 2)
- ;
- issue7978cb();
- __atomic_add_fetch(sync, 1, __ATOMIC_SEQ_CST);
- while(__atomic_load_n(sync, __ATOMIC_SEQ_CST) != 6)
- ;
-}
-
// issue 8331 part 2 - part 1 in test.go
// A typedef of an unnamed struct is the same struct when
// #include'd twice. No runtime test; just make sure it compiles.
}
}
-// issue 7978
-
-var issue7978sync uint32
-
-func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
- runtime.GC()
- buf := make([]byte, 65536)
- trace := string(buf[:runtime.Stack(buf, true)])
- for _, goroutine := range strings.Split(trace, "\n\n") {
- if strings.Contains(goroutine, "test.issue7978go") {
- trace := strings.Split(goroutine, "\n")
- // look for the expected function in the stack
- for i := 0; i < depth; i++ {
- if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
- t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
- return
- }
- if strings.Contains(trace[1+2*i], wantFunc) {
- return
- }
- }
- t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
- return
- }
- }
- t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
-}
-
-func issue7978wait(store uint32, wait uint32) {
- if store != 0 {
- atomic.StoreUint32(&issue7978sync, store)
- }
- for atomic.LoadUint32(&issue7978sync) != wait {
- runtime.Gosched()
- }
-}
-
-//export issue7978cb
-func issue7978cb() {
- // Force a stack growth from the callback to put extra
- // pressure on the runtime. See issue #17785.
- growStack(64)
- issue7978wait(3, 4)
-}
-
-func growStack(n int) int {
- var buf [128]int
- if n == 0 {
- return 0
- }
- return buf[growStack(n-1)]
-}
-
-func issue7978go() {
- C.issue7978c((*C.uint32_t)(&issue7978sync))
- issue7978wait(7, 8)
-}
-
-func test7978(t *testing.T) {
- if runtime.Compiler == "gccgo" {
- t.Skip("gccgo can not do stack traces of C code")
- }
- debug.SetTraceback("2")
- issue7978sync = 0
- go issue7978go()
- // test in c code, before callback
- issue7978wait(0, 1)
- issue7978check(t, "_Cfunc_issue7978c(", "", 1)
- // test in go code, during callback
- issue7978wait(2, 3)
- issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
- // test in c code, after callback
- issue7978wait(4, 5)
- issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
- // test in go code, after return from cgo
- issue7978wait(6, 7)
- issue7978check(t, "test.issue7978go(", "", 3)
- atomic.StoreUint32(&issue7978sync, 8)
-}
-
// issue 8331 part 2
var issue8331Var C.issue8331
if t.supportedBuildmode("pie") {
t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie")
if t.internalLink() && t.internalLinkPIE() {
- t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal")
+ t.addCmd(dt, "misc/cgo/test", t.goTest(), "-buildmode=pie", "-ldflags=-linkmode=internal", "-tags=internal")
}
t.addCmd(dt, "misc/cgo/testtls", t.goTest(), "-buildmode=pie")
t.addCmd(dt, "misc/cgo/nocgo", t.goTest(), "-buildmode=pie")