Hi all,
fatal error: checkptr: unsafe pointer arithmetic
The offending line is:
oggfile := C.op_open_callbacks(
unsafe.Pointer(s.id), // <-- this guy
&C.callbacks,
nil,
0,
&errno)
Background: I need to pass a reference to a go struct to that C call, so when it calls my callback function, that callback function can find the Go struct. The C function expects a void *, but I have a map[uintptr]myType locally with a fresh int for every new struct. I cast that uintptr to an unsafe.Pointer, pass that to the C call, and once the callback is called, I cast it back to a uintptr, and use that to fetch the relevant struct from the map. That's what the "
s.id" thing is.
If I understand correctly, since 1.14 (?) go test -race includes -d=checkptr, and checkptr does not like arbitrary uintptrs to be case to unsafe.Pointer. However, as far as I understand, that error is spurious in my specific case, because nobody ever dereferences the pointer at all, or does any arithmetic on it; it's only cast straight back to a uintptr.
Question 2: if it is necessary, is this "arbitrary uintptr in void *" valid? As far as I understand the C standard, it is, but again maybe I misunderstood.
Question 3: If it is valid, what can / should I do about go test -race?
Thanks all and kind regards
Hraban
Full go test -race output:
fatal error: checkptr: unsafe pointer arithmetic
goroutine 56 [running]:
runtime.throw(0x42354f9, 0x23)
/usr/local/opt/go/libexec/src/runtime/panic.go:1116 +0x72 fp=0xc000048ce0 sp=0xc000048cb0 pc=0x4034c22
runtime.checkptrArithmetic(0x40, 0x0, 0x0, 0x0)
/usr/local/opt/go/libexec/src/runtime/checkptr.go:26 +0xce fp=0xc000048d10 sp=0xc000048ce0 pc=0x400859e
_/Users/hraban/code/personal/opus.(*Stream).Init.func1(0xc0001525c0, 0xc000128758, 0x1)
/Users/hraban/code/personal/opus/stream.go:108 +0x6a fp=0xc000048d68 sp=0xc000048d10 pc=0x419ddba
_/Users/hraban/code/personal/opus.(*Stream).Init(0xc0001525c0, 0x42630c0, 0xc0001323e0, 0x0, 0x0)
/Users/hraban/code/personal/opus/stream.go:112 +0x277 fp=0xc000048e38 sp=0xc000048d68 pc=0x419a9c7
_/Users/hraban/code/personal/opus.NewStream(0x42630c0, 0xc0001323e0, 0x0, 0x0, 0x0)
/Users/hraban/code/personal/opus/stream.go:75 +0xa0 fp=0xc000048e88 sp=0xc000048e38 pc=0x419a6b0
_/Users/hraban/code/personal/opus.TestStreamIllegal(0xc0002fcb40)
/Users/hraban/code/personal/opus/stream_test.go:20 +0xc0 fp=0xc000048ed0 sp=0xc000048e88 pc=0x4194320
testing.tRunner(0xc0002fcb40, 0x4238c08)
/usr/local/opt/go/libexec/src/testing/testing.go:991 +0x1ec fp=0xc000048fd0 sp=0xc000048ed0 pc=0x41270ec
runtime.goexit()
/usr/local/opt/go/libexec/src/runtime/asm_amd64.s:1373 +0x1 fp=0xc000048fd8 sp=0xc000048fd0 pc=0x4066851
created by testing.(*T).Run
/usr/local/opt/go/libexec/src/testing/testing.go:1042 +0x661
goroutine 1 [chan receive]:
testing.(*T).Run(0xc000156000, 0x4230a45, 0x11, 0x4238c08, 0x1)
/usr/local/opt/go/libexec/src/testing/testing.go:1043 +0x699
testing.runTests.func1(0xc000156000)
/usr/local/opt/go/libexec/src/testing/testing.go:1284 +0xa7
testing.tRunner(0xc000156000, 0xc00013bd50)
/usr/local/opt/go/libexec/src/testing/testing.go:991 +0x1ec
testing.runTests(0xc000132040, 0x437c680, 0x1d, 0x1d, 0x0)
/usr/local/opt/go/libexec/src/testing/testing.go:1282 +0x528
testing.(*M).Run(0xc000154000, 0x0)
/usr/local/opt/go/libexec/src/testing/testing.go:1199 +0x300
main.main()
_testmain.go:100 +0x224
exit status 2
FAIL _/Users/hraban/code/personal/opus 0.231s