From c72ca180d0949822a3ea2216e973559b21136b18 Mon Sep 17 00:00:00 2001 From: Xiangdong Ji Date: Wed, 5 Aug 2020 06:02:58 +0000 Subject: [PATCH] fix build failure of misc/cgo/test on arm64 Origin: backport, https://golang.org/cl/237858 Gbp-Pq: Name 0005-fix-build-failure-of-misc-cgo-test-on-arm64.patch --- misc/cgo/test/issue7978.go | 117 ++++++++++++++++++++++++++++++++++++ misc/cgo/test/issue7978b.go | 24 ++++++++ misc/cgo/test/testx.go | 105 -------------------------------- 3 files changed, 141 insertions(+), 105 deletions(-) create mode 100644 misc/cgo/test/issue7978.go create mode 100644 misc/cgo/test/issue7978b.go diff --git a/misc/cgo/test/issue7978.go b/misc/cgo/test/issue7978.go new file mode 100644 index 00000000..c08c5bc6 --- /dev/null +++ b/misc/cgo/test/issue7978.go @@ -0,0 +1,117 @@ +// 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 + +package cgotest + +import ( + "runtime" + "runtime/debug" + "strings" + "sync/atomic" + "testing" +) + +/* +#include + +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) +} diff --git a/misc/cgo/test/issue7978b.go b/misc/cgo/test/issue7978b.go new file mode 100644 index 00000000..4a16d90e --- /dev/null +++ b/misc/cgo/test/issue7978b.go @@ -0,0 +1,24 @@ +// 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 + +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") +} diff --git a/misc/cgo/test/testx.go b/misc/cgo/test/testx.go index eb9d7fa4..2919a9f4 100644 --- a/misc/cgo/test/testx.go +++ b/misc/cgo/test/testx.go @@ -12,10 +12,7 @@ package cgotest import ( "runtime" - "runtime/debug" - "strings" "sync" - "sync/atomic" "testing" "time" "unsafe" @@ -75,28 +72,6 @@ extern int CheckIssue6907C(_GoString_); 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 - -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. @@ -440,86 +415,6 @@ func test7665(t *testing.T) { } } -// 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 -- 2.30.2