【踩了一个坑】golang 中使用 unsafe,在 ARM64 下出现错误 `signal SIGBUS`
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
为了去掉数组的下标越界检查,于是把数组访问改成 unsafe 的指针访问。
运行时出现无法调试无法捕获的错误:
unexpected fault address 0x14001c00000
fatal error: fault
[signal SIGBUS: bus error code=0x1 addr=0x14001c00000 pc=0x100303238]
goroutine 46 gp=0x14000187dc0 m=8 mp=0x14000aa2008 [running]:
runtime.throw({0x10058a7fa?, 0x100167544?})
/Users/ahfuzhang/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.3.darwin-arm64/src/runtime/panic.go:1101 +0x38 fp=0x14000068e80 sp=0x14000068e50 pc=0x100166b88
runtime.sigpanic()
/Users/ahfuzhang/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.24.3.darwin-arm64/src/runtime/signal_unix.go:922 +0x170 fp=0x14000068ee0 sp=0x14000068e80 pc=0x100168510
github.com/VictoriaMetrics/VictoriaMetrics/lib/logstorage.initBloomFilterV4({0x14000280000?, 0x10016a7dc?, 0x1e7fa361f17fd?}, {0x14000b00000?, 0x132efed8001e97b4?, 0x684b8b98?})
最后的我的大神 Vayala 告诉了我原因:
This may result in unaligned load of uint64. While this is OK for GOARCH=amd64 - this results only in a slight slowdown, this doesn't work for GOARCH=arm64 - it results in SIGBUS crash as I know.
在 ARM64 架构下,对内存访问的对齐要求比 x86 严格,如果对未对齐的地址进行某些类型的数据访问,可能会触发 SIGBUS(bus error)。
对齐的要求如下:
| 数据类型 | 所需对齐(字节) |
|---|---|
| uint8_t | 1 字节 |
| uint16_t | 2 字节 |
| uint32_t | 4 字节 |
| uint64_t | 8 字节 |
| float | 4 字节 |
| double | 8 字节 |
| uint128_t | 16 字节 |

浙公网安备 33010602011771号