golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.63k stars 17.49k forks source link

x/mobile: fatal error: bulkBarrierPreWrite: unaligned arguments #46893

Open champo opened 3 years ago

champo commented 3 years ago

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:

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.

rayvbr commented 3 years ago

I've encountered this problem as well in the past, issue started with Go 1.16 (1.15 seems unaffected). In my case I had a function signature func DoSomething(i int32, s string) (string, error). Changing that to func DoSomething(s string, i int32) (string, error) resolved the issue. I never really understood why

hilariocoelho commented 3 years ago

I had the same issue using Go 1.16. Reverted to Go 1.13 and it works fine. Also just affected a few users and couldn't reproduce it consistently.

marinthiercelin commented 3 years ago

I have experienced the same issue using https://github.com/ProtonMail/gopenpgp in an iOS app (with gomobile). The issue has been reproduced when building the library with golang 1.16, 1.16.5 and 1.16.6. Building with golang 1.15.14 works fine.

elagergren-spideroak commented 2 years ago

Can 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 typedmemmove to crash. For exampe: _cgoexp_432d4433717a_proxygolib_Client_Query(0x16f8557d4).

I think this is a cmd/cgo problem, not x/mobile. cc: @ianlancetaylor

elagergren-spideroak commented 2 years ago

An update: we patched cmd/cgo with __attribute__((aligned(8))) and it fixes the problem.

hilariocoelho commented 2 years ago

@elagergren-spideroak when should we expect a release that fixes it, do you have any idea?

elagergren-spideroak commented 2 years ago

I am not a member of the Go team, so I am not the person to ask. However, I'm going to submit a CL with the patch to get things started.

sanderdekoning commented 2 years ago

Bump - just ran into this: fatal error: bulkBarrierPreWrite: unaligned arguments

sanderdekoning commented 2 years ago

@elagergren-spideroak just to know if I/we can assist in any way, the current status is what exactly? Thanks for letting us know how you fixed it!

champo commented 2 years ago

@elagergren-spideroak thanks for looking into this! Did you get a chance to make the CL? If you didn't, I'd really appreciate a gist so I can patch locally for the time being. I just got a new batch of ocurrences of this I can't seem to sidestep :(

elagergren-spideroak commented 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

fmt.Fprintf(fgcc, "\ttypedef %s %v __attribute__((aligned(8))) _cgo_argtype;\n", ctype, p.packedAttribute())
champo commented 2 years ago

Thanks @elagergren-spideroak! Just tested it out and works great šŸ‘Œ

alock commented 2 years ago

I am not a member of the Go team, so I am not the person to ask. However, I'm going to submit a CL with the patch to get things started.

@elagergren-spideroak Where you able to create a CL? If so can you share the link to follow here.

gopherbot commented 2 years ago

Change https://go.dev/cl/408395 mentions this issue: cmd/cgo: fix unaligned arguments typedmemmove crash on iOS

lixin9311 commented 2 years ago

Thanks for the fix. It fixed our runtime.raise_trampoline crashed.

junyang100 commented 2 years ago

I just started using Golang. Can anyone tell me if I need to recompile the Golang or just need to rebuild my project after I change the source code

jeffrrogers commented 1 year ago

@gopherbot This still seems to be an issue when running on ARM architecture (MacOS M1 or iOS devices). We compiled our framework with Go version 1.19.4 on both Intel and M1 machines, and it runs fine on Intel machine simulators, but crashes intermittently on M1 machine simulators and iOS devices. This was supposed to be fixed in 1.19.2 right? Here is the stack trace we get for our crash:

fatal error: bulkBarrierPreWrite: unaligned arguments

goroutine 17 [running, locked to thread]: runtime.throw({0x1013583ac?, 0x1300ddd08?}) /usr/local/go/src/runtime/panic.go:1047 +0x40 fp=0x1300ddce0 sp=0x1300ddcb0 pc=0x101095a90 runtime.bulkBarrierPreWrite(0x1300ddd78?, 0x0?, 0x130543530?) /usr/local/go/src/runtime/mbitmap.go:582 +0x420 fp=0x1300ddd50 sp=0x1300ddce0 pc=0x1010759c0 runtime.typedmemmove(0x1014ba460, 0x16f4eb6bc, 0x1300ddde8) /usr/local/go/src/runtime/mbarrier.go:162 +0x48 fp=0x1300ddd90 sp=0x1300ddd50 pc=0x101074bd8 _cgoexp_409b037657a8_proxyswiftgold_SwiftGoLD_Normalize(0x16f4eb6a4) _cgo_gotypes.go:168 +0xa4 fp=0x1300dde00 sp=0x1300ddd90 pc=0x1012900d4 runtime.cgocallbackg1(0x101290030, 0x1300ddfe0?, 0x0) /usr/local/go/src/runtime/cgocall.go:316 +0x244 fp=0x1300ddef0 sp=0x1300dde00 pc=0x1010653a4 runtime.cgocallbackg(0x0?, 0x0?, 0x0?) /usr/local/go/src/runtime/cgocall.go:235 +0xd8 fp=0x1300ddf80 sp=0x1300ddef0 pc=0x1010650d8 runtime.cgocallbackg(0x101290030, 0x16f4eb6a4, 0x0) :1 +0x1c fp=0x1300ddfb0 sp=0x1300ddf80 pc=0x1010c694c runtime.cgocallback(0x0, 0x0, 0x0) /usr/local/go/src/runtime/asm_arm64.s:1094 +0xa0 fp=0x1300ddfe0 sp=0x1300ddfb0 pc=0x1010c52b0 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1300ddfe0 sp=0x1300ddfe0 pc=0x1010c5384

goroutine 21 [GC worker (idle)]: runtime.gopark(0x18ff8289ace30?, 0x2?, 0x70?, 0x31?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x13003cf40 sp=0x13003cf20 pc=0x1010983d4 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1235 +0xec fp=0x13003cfd0 sp=0x13003cf40 pc=0x10107c20c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x13003cfd0 sp=0x13003cfd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

goroutine 2 [force gc (idle)]: runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x13003ffa0 sp=0x13003ff80 pc=0x1010983d4 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:369 runtime.forcegchelper() /usr/local/go/src/runtime/proc.go:302 +0xac fp=0x13003ffd0 sp=0x13003ffa0 pc=0x10109826c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x13003ffd0 sp=0x13003ffd0 pc=0x1010c5384 created by runtime.init.6 /usr/local/go/src/runtime/proc.go:290 +0x24

goroutine 3 [GC sweep wait]: runtime.gopark(0x1?, 0x0?, 0x0?, 0x0?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x130040f70 sp=0x130040f50 pc=0x1010983d4 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:369 runtime.bgsweep(0x0?) /usr/local/go/src/runtime/mgcsweep.go:297 +0x10c fp=0x130040fb0 sp=0x130040f70 pc=0x10108586c runtime.gcenable.func1() /usr/local/go/src/runtime/mgc.go:178 +0x28 fp=0x130040fd0 sp=0x130040fb0 pc=0x10107a0a8 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x130040fd0 sp=0x130040fd0 pc=0x1010c5384 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:178 +0x74

goroutine 4 [GC scavenge wait]: runtime.gopark(0x1f4dfcc?, 0xbf69ca?, 0x0?, 0x0?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x130041f50 sp=0x130041f30 pc=0x1010983d4 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:369 runtime.(*scavengerState).park(0x10171be40) /usr/local/go/src/runtime/mgcscavenge.go:389 +0x5c fp=0x130041f80 sp=0x130041f50 pc=0x1010837bc runtime.bgscavenge(0x0?) /usr/local/go/src/runtime/mgcscavenge.go:622 +0xac fp=0x130041fb0 sp=0x130041f80 pc=0x101083dcc runtime.gcenable.func2() /usr/local/go/src/runtime/mgc.go:179 +0x28 fp=0x130041fd0 sp=0x130041fb0 pc=0x10107a048 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x130041fd0 sp=0x130041fd0 pc=0x1010c5384 created by runtime.gcenable /usr/local/go/src/runtime/mgc.go:179 +0xb8

goroutine 18 [finalizer wait]: runtime.gopark(0x10171c6e0?, 0x130082340?, 0x0?, 0x0?, 0x1?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x13003ed80 sp=0x13003ed60 pc=0x1010983d4 runtime.goparkunlock(...) /usr/local/go/src/runtime/proc.go:369 runtime.runfinq() /usr/local/go/src/runtime/mfinal.go:180 +0x124 fp=0x13003efd0 sp=0x13003ed80 pc=0x1010792d4 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x13003efd0 sp=0x13003efd0 pc=0x1010c5384 created by runtime.createfing /usr/local/go/src/runtime/mfinal.go:157 +0x84

goroutine 19 [select, locked to thread]: runtime.gopark(0x13003afa0?, 0x2?, 0x88?, 0xae?, 0x13003af9c?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x13003ae30 sp=0x13003ae10 pc=0x1010983d4 runtime.selectgo(0x13003afa0, 0x13003af98, 0x0?, 0x0, 0x0?, 0x1) /usr/local/go/src/runtime/select.go:328 +0x68c fp=0x13003af50 sp=0x13003ae30 pc=0x1010a821c runtime.ensureSigM.func1() /usr/local/go/src/runtime/signal_unix.go:991 +0x190 fp=0x13003afd0 sp=0x13003af50 pc=0x1010ac2c0 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x13003afd0 sp=0x13003afd0 pc=0x1010c5384 created by runtime.ensureSigM /usr/local/go/src/runtime/signal_unix.go:974 +0xf4

goroutine 20 [syscall]: runtime.sigNoteSleep(0x0) /usr/local/go/src/runtime/os_darwin.go:123 +0x20 fp=0x13003bf90 sp=0x13003bf50 pc=0x101092c70 os/signal.signal_recv() /usr/local/go/src/runtime/sigqueue.go:149 +0x2c fp=0x13003bfb0 sp=0x13003bf90 pc=0x1010c183c os/signal.loop() /usr/local/go/src/os/signal/signal_unix.go:23 +0x1c fp=0x13003bfd0 sp=0x13003bfb0 pc=0x10128f74c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x13003bfd0 sp=0x13003bfd0 pc=0x1010c5384 created by os/signal.Notify.func1.1 /usr/local/go/src/os/signal/signal.go:151 +0x2c

goroutine 35 [runnable]: runtime.gcMarkDone() /usr/local/go/src/runtime/mgc.go:784 +0x304 fp=0x1305e6f40 sp=0x1305e6f40 pc=0x10107b044 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1367 +0x3c0 fp=0x1305e6fd0 sp=0x1305e6f40 pc=0x10107c4e0 runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1305e6fd0 sp=0x1305e6fd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

goroutine 36 [GC worker (idle)]: runtime.gopark(0x18ff819afa669?, 0x13045c800?, 0x18?, 0x14?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x1305e7f40 sp=0x1305e7f20 pc=0x1010983d4 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1235 +0xec fp=0x1305e7fd0 sp=0x1305e7f40 pc=0x10107c20c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1305e7fd0 sp=0x1305e7fd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

goroutine 5 [GC worker (idle)]: runtime.gopark(0x18ff7e15e0483?, 0x2?, 0x44?, 0x4f?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x1305e2f40 sp=0x1305e2f20 pc=0x1010983d4 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1235 +0xec fp=0x1305e2fd0 sp=0x1305e2f40 pc=0x10107c20c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1305e2fd0 sp=0x1305e2fd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

goroutine 37 [GC worker (idle)]: runtime.gopark(0x18ff82e592446?, 0x2?, 0x5e?, 0xa0?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x1305e8f40 sp=0x1305e8f20 pc=0x1010983d4 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1235 +0xec fp=0x1305e8fd0 sp=0x1305e8f40 pc=0x10107c20c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1305e8fd0 sp=0x1305e8fd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

goroutine 38 [GC worker (idle)]: runtime.gopark(0x18ff82e55881f?, 0x1?, 0x84?, 0x8f?, 0x0?) /usr/local/go/src/runtime/proc.go:363 +0xe4 fp=0x1305e9f40 sp=0x1305e9f20 pc=0x1010983d4 runtime.gcBgMarkWorker() /usr/local/go/src/runtime/mgc.go:1235 +0xec fp=0x1305e9fd0 sp=0x1305e9f40 pc=0x10107c20c runtime.goexit() /usr/local/go/src/runtime/asm_arm64.s:1172 +0x4 fp=0x1305e9fd0 sp=0x1305e9fd0 pc=0x1010c5384 created by runtime.gcBgMarkStartWorkers /usr/local/go/src/runtime/mgc.go:1159 +0x28

randall77 commented 1 year ago

I don't think this has actually been fixed yet. There is a CL (https://go-review.googlesource.com/c/go/+/408395) but it hasn't been checked in yet.

55122 has been fixed and backported, but I don't think that's the same issue as this one. This one has to do with cgo.

stoffen commented 8 months ago

This issue persist on 1.21.5.

A slightly simpler repro of the issue (fatal error: bulkBarrierPreWrite: unaligned arguments), run this in a tight loop from iOS on Apple Silicon:

func (p *Server) GoPanicIssue(_ string) ([]byte, error) {
    return []byte{0}, nil
}

Not able to repro with the suggested cgo alignment fix

arantes555 commented 8 months ago

I ran into the same issue for the Go library we are writing: random crashes on iOS, with similar error messages.

I can confirm that a build done with a Go toolchain that includes the suggested fix does not crash.

creamwhip commented 5 months ago

This is still an issue with the latest go 1.22.1 on arm64.

We've been running the suggested patch for some time, with no adverse effects, so why we can't just get it merged in is a complete mystery.

Is anyone watching these issues?

randall77 commented 5 months ago

The patch was never finished by the author. @ianlancetaylor

creamwhip commented 5 months ago

@randall77 this is completely perfect as a fix:

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

fmt.Fprintf(fgcc, "\ttypedef %s %v __attribute__((aligned(8))) _cgo_argtype;\n", ctype, p.packedAttribute())
randall77 commented 5 months ago

Sure, it works, but that doesn't mean the patch is perfect. If you read the CL comments, it's not right for 32-bit systems, and there's no test.

gopherbot commented 5 months ago

Change https://go.dev/cl/571375 mentions this issue: cmd/cgo: fix unaligned arguments typedmemmove crash on iOS

stoffen commented 5 months ago

Our users can confirm this is a showstopper for us using GoMobile. Our apps renders useless without that patch. Have no idea how to express it in a test or fix it for 32-bits, though

ons. 13. mars 2024 kl. 20:25 skrev GopherBot @.***>:

Change https://go.dev/cl/571375 mentions this issue: cmd/cgo: fix unaligned arguments typedmemmove crash on iOS

ā€” Reply to this email directly, view it on GitHub https://github.com/golang/go/issues/46893#issuecomment-1995484485, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJRBNRFEVHHQHNGE742JW3YYCR23AVCNFSM47GHEIEKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJZGU2DQNBUHA2Q . You are receiving this because you commented.Message ID: @.***>

ianlancetaylor commented 5 months ago

Although the patch seems to focus on forcing the alignment of a variable in cgo-generated code, the problem seems to be that the stack is not aligned to what Go expects. Is that correct? That suggests that a better fix would be to align the stack pointer when calling from C to Go.

andrewmostello commented 3 months ago

To bump this issue: we ran into it in our first few days of experimenting with gomobile for our iOS project. As noted above, this (abandoned?) fix resolves the problem: https://go-review.googlesource.com/c/go/+/571375/5/src/cmd/cgo/out.go

I would not have expected to need to modify and compile the toolchain, but it seems like gomobile doesn't work without this for iOS. We're not doing anything special as far as I can tell, just a gomobile bind library for an iOS app.