go: x/mobile: fatal error: bulkBarrierPreWrite: unaligned arguments
What version of Go are you using (go version)?
$ go version go version go1.16.5 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/Users/juancivile/Library/Caches/go-build" GOENV="/Users/juancivile/Library/Application Support/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/juancivile/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="darwin" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/Cellar/go/1.16.5/libexec" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/Cellar/go/1.16.5/libexec/pkg/tool/darwin_amd64" GOVCS="" GOVERSION="go1.16.5" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/ln/73tvl7md2l7gqpbkzq439dcc0000gn/T/go-build3867799831=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I have an iOS project using a go library via gomobile:
- Running on an arm64 device (any modern iPhone)
- Calling a method that takes and returns
[]byte - A ton of invocations. This is affecting randomly about 1-2% of users of our app.
The golang code is simple:
type Panicker interface {
Panic([]byte) ([]byte, error)
}
type PanickerImpl struct {
}
func (p *PanickerImpl) Panic(b []byte) ([]byte, error) {
return make([]byte, len(b)), nil
}
func Init() {
debug.SetTraceback("crash")
}
And on swift:
PanickerInit()
let p = PanickerPanickerImpl()
let d = Data(repeating: 1, count: 10)
for _ in 1...10_000_000 {
let r = try p.panic(d)
XCTAssertEqual(r.count, d.count)
}
A full working reproduction project is at https://github.com/champo/gomobile_panic
What did you expect to see?
No crash.
What did you see instead?
It sometimes crashes inside bulkBarrierPreWrite:
fatal error: bulkBarrierPreWrite: unaligned arguments
goroutine 17 [running, locked to thread]:
runtime.throw(0x1014aeaa4, 0x28)
runtime/panic.go:1117 +0x54 fp=0x130582d30 sp=0x130582d00 pc=0x1014373d4
runtime.bulkBarrierPreWrite(0x16f5e483c, 0x130582e68, 0x8)
runtime/mbitmap.go:554 +0x44c fp=0x130582dd0 sp=0x130582d30 pc=0x101419f0c
runtime.typedmemmove(0x1014e0000, 0x16f5e483c, 0x130582e68)
runtime/mbarrier.go:161 +0xa4 fp=0x130582e10 sp=0x130582dd0 pc=0x1014190c4
_cgoexp_59f89a9c1f1d_proxypanicker_PanickerImpl_Panic(0x16f5e4824)
_cgo_gotypes.go:183 +0xe8 fp=0x130582e80 sp=0x130582e10 pc=0x1014a3068
runtime.cgocallbackg1(0x1014a2f80, 0x16f5e4824, 0x0)
runtime/cgocall.go:292 +0x140 fp=0x130582f40 sp=0x130582e80 pc=0x10140a9e0
runtime.cgocallbackg(0x1014a2f80, 0x16f5e4824, 0x0)
runtime/cgocall.go:228 +0xb0 fp=0x130582fb0 sp=0x130582f40 pc=0x10140a810
runtime.cgocallback(0x0, 0x0, 0x0)
runtime/asm_arm64.s:1055 +0x98 fp=0x130582fe0 sp=0x130582fb0 pc=0x1014687f8
runtime.goexit()
runtime/asm_arm64.s:1130 +0x4 fp=0x130582fe0 sp=0x130582fe0 pc=0x1014688d4
I tried exposing a free function with a similar signature but no crashers there. Removing the paramters or return values seems to avoid the crash too.
About this issue
- Original URL
- State: open
- Created 3 years ago
- Reactions: 5
- Comments: 19 (1 by maintainers)
Commits related to this issue
- cmd/cgo: fix unaligned arguments typedmemmove crash on iOS Irregularly typedmemmove and bulkBarrierPreWrite crashes on unaligned arguments. By aligning the arguments on 8 bytes this is fixed. Fixes ... — committed to timcooijmans/go by timcooijmans 2 years ago
- cmd/cgo: fix unaligned arguments typedmemmove crash on iOS Irregularly typedmemmove and bulkBarrierPreWrite crashes on unaligned arguments. By aligning the arguments on 8 bytes this is fixed. Fixes ... — committed to stoffen/go by timcooijmans 2 years ago
- cmd/cgo: fix unaligned arguments typedmemmove crash on iOS Irregularly typedmemmove and bulkBarrierPreWrite crashes on unaligned arguments. By aligning the arguments on 8 bytes this is fixed. Fixes ... — committed to stoffen/go by timcooijmans 2 years ago
How we’ve fixed it for our iOS builds is by replacing https://github.com/golang/go/blob/97e740e8b0ff1b32b164b0cbef06c12c4d591f3f/src/cmd/cgo/out.go#L1005 with
An update: we patched
cmd/cgowith__attribute__((aligned(8)))and it fixes the problem.Change https://go.dev/cl/408395 mentions this issue:
cmd/cgo: fix unaligned arguments typedmemmove crash on iOSCan consistently repro with 1.17.x on iOS. It occurs when calling into Go from C. The stack frame C sets up for Go is four-byte aligned, which makes it likely that the address of the results aren’t properly aligned, and therefore casues
typedmemmoveto crash. For exampe:_cgoexp_432d4433717a_proxygolib_Client_Query(0x16f8557d4).I think this is a
cmd/cgoproblem, notx/mobile. cc: @ianlancetaylor