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