darwin/arm64: checkptr panic in _unixModeBit when using race detector
# darwin/arm64: checkptr panic in _unixModeBit when using race detector
## Summary
When running with Go's race detector (`-race`), calling `FileControlPersistWAL` triggers a fatal `checkptr: pointer arithmetic result points to invalid allocation` panic in `_unixModeBit`.
## Environment
- **OS:** macOS 15.3 (Darwin 25.1.0)
- **Architecture:** arm64 (Apple Silicon M1/M2/M3)
- **Go version:** go1.25.5 darwin/arm64
- **modernc.org/sqlite version:** v1.44.2
## Minimal Reproducer
```go
package main
import (
"database/sql"
"os"
"path/filepath"
"testing"
"modernc.org/sqlite"
)
func TestFileControlPersistWAL_Checkptr(t *testing.T) {
dir := t.TempDir()
dbPath := filepath.Join(dir, "test.db")
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(wal)")
if err != nil {
t.Fatalf("failed to open database: %v", err)
}
defer db.Close()
if _, err := db.Exec("CREATE TABLE test (id INTEGER PRIMARY KEY)"); err != nil {
t.Fatalf("failed to create table: %v", err)
}
conn, err := db.Conn(t.Context())
if err != nil {
t.Fatalf("failed to get connection: %v", err)
}
defer conn.Close()
err = conn.Raw(func(driverConn interface{}) error {
fc, ok := driverConn.(sqlite.FileControl)
if !ok {
t.Fatal("driver does not implement FileControl")
}
// This triggers the checkptr panic with -race
_, err := fc.FileControlPersistWAL("main", 1)
return err
})
if err != nil {
t.Fatalf("FileControlPersistWAL failed: %v", err)
}
}
```
## Steps to Reproduce
1. Save the above code as `main_test.go`
2. Run `go mod init reproducer && go get modernc.org/sqlite@v1.44.2`
3. Run `go test -v ./...` - **PASSES**
4. Run `go test -race -v ./...` - **PANICS**
## Stack Trace
```
fatal error: checkptr: pointer arithmetic result points to invalid allocation
goroutine 8 gp=0xc00060a8c0 m=0 mp=0x103209120 [running]:
runtime.throw({0x102deac4c?, 0x102871d30?})
/opt/homebrew/Cellar/go/1.25.5/libexec/src/runtime/panic.go:1094 +0x34
runtime.checkptrArithmetic(0x10c400060?, {0x0, 0x0, 0x10?})
/opt/homebrew/Cellar/go/1.25.5/libexec/src/runtime/checkptr.go:69 +0xa8
modernc.org/sqlite/lib._unixModeBit(0xc000129e10?, 0x10c4719b0, 0x4, 0xc0001144bc)
/Users/.../modernc.org/sqlite@v1.44.2/lib/sqlite_darwin_arm64.go:27318 +0x4c
modernc.org/sqlite/lib._unixFileControl(0xc000129e10, 0x10c4719b0, 0xa, 0xc0001144bc)
/Users/.../modernc.org/sqlite@v1.44.2/lib/sqlite_darwin_arm64.go:27362 +0x36c
modernc.org/sqlite/lib._sqlite3OsFileControl(...)
/Users/.../modernc.org/sqlite@v1.44.2/lib/sqlite_darwin_arm64.go:14670
modernc.org/sqlite/lib.Xsqlite3_file_control(...)
/Users/.../modernc.org/sqlite@v1.44.2/lib/sqlite_darwin_arm64.go:167706 +0x3bc
modernc.org/sqlite.(*conn).fileControl(...)
/Users/.../modernc.org/sqlite@v1.44.2/fcntl.go:42 +0xd8
modernc.org/sqlite.(*conn).FileControlPersistWAL(...)
/Users/.../modernc.org/sqlite@v1.44.2/fcntl.go:31 +0xc8
```
## Analysis
The panic occurs in `_unixModeBit` at `lib/sqlite_darwin_arm64.go:27318`. Looking at the code:
```go
func _unixModeBit(tls *libc.TLS, pFile uintptr, unixOp int8, pArg uintptr) int32 {
// ... pointer arithmetic that triggers checkptr
}
```
The `checkptr` instrumentation in Go's race detector validates that pointer arithmetic results point to valid allocations. The transpiled C code in `_unixModeBit` appears to perform pointer arithmetic that the race detector flags as invalid.
This is likely a false positive from `checkptr`'s perspective - the code works correctly without `-race` - but it prevents using the race detector for testing applications that use `FileControlPersistWAL`.
## Impact
This affects projects like [Litestream](https://github.com/benbjohnson/litestream) which use `FileControlPersistWAL` and want to run their test suites with the race detector enabled.
Related: https://github.com/benbjohnson/litestream/issues/1014
## Possible Solutions
1. Investigate the pointer arithmetic in `_unixModeBit` and adjust the ccgo transpilation to produce checkptr-compatible code
2. Add `//go:nocheckptr` directive to the affected functions (if appropriate)
3. Document as a known limitation when using `-race`
## Related Issues
- [#77 - Race in ./lib.unixTempFileDir](https://gitlab.com/cznic/sqlite/-/issues/77)
- [#62 - Race on sqlite3_open_v2/sqlite3_initialize on darwin/amd64](https://gitlab.com/cznic/sqlite/-/issues/62)
- [cznic/libc#8 - windows/amd64: race detector triggers checkptr failure](https://gitlab.com/cznic/libc/-/issues/8)
issue