Error unexpected fault address
might be triggered by data race or memory
corruption. With fully code review, I prefer memory corruption rather data race.
the following code panics occasionally, and yes, even when I initialize silces.
package controlcan
import "C"
cReceive := make([]C.struct__CAN_OBJ, 2500)
or
package main
import "controlcan"
pReceive := make([]controlcan.CanObj, 2500)
Both of them trigger the error occasionally:
unexpected fault address 0xffffffffffffffff
fatal error: fault
[signal 0xc0000005 code=0x0 addr=0xffffffffffffffff pc=0x41c65d]
goroutine 41 [running]:
runtime.throw(0xcc969a, 0x5)
/usr/local/go/src/runtime/panic.go:619 +0x88 fp=0xc0428ffb38 sp=0xc0428ffb18 pc=0x42d0b8
runtime.sigpanic()
/usr/local/go/src/runtime/signal_windows.go:170 +0x13a fp=0xc0428ffb68 sp=0xc0428ffb38 pc=0x43fcca
runtime.gcMarkRootPrepare()
/usr/local/go/src/runtime/mgcmark.go:72 +0x5d fp=0xc0428ffb70 sp=0xc0428ffb68 pc=0x41c65d
runtime.gcStart(0x0, 0x1, 0x0, 0x0)
/usr/local/go/src/runtime/mgc.go:1350 +0x30f fp=0xc0428ffba0 sp=0xc0428ffb70 pc=0x419b6f
runtime.mallocgc(0x10000, 0xc54660, 0xc0422ee001, 0xc0423ded60)
/usr/local/go/src/runtime/malloc.go:803 +0x448 fp=0xc0428ffc40 sp=0xc0428ffba0 pc=0x411c48
runtime.makeslice(0xc54660, 0x9c4, 0x9c4, 0xc04202ce00, 0xc04202c000, 0x411b23)
/usr/local/go/src/runtime/slice.go:61 +0x7e fp=0xc0428ffc70 sp=0xc0428ffc40 pc=0x43fffe
controlcan.Receive(0x4, 0x0, 0x0, 0xc04267e000, 0x9c4, 0x9c4, 0x64, 0x0, 0x0, 0x0)
/media/sf_GOPATH0/src/controlcan/controlcan.go:262 +0x75 fp=0xc0428ffd70 sp=0xc0428ffc70 pc=0xa0d795
posam/protocol/usbcan.(*Channel).receive(0xc04229d490)
/media/sf_GOPATH0/src/posam/protocol/usbcan/usbcan.go:469 +0x536 fp=0xc0428fffd8 sp=0xc0428ffd70 pc=0xa10926
runtime.goexit()
/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc0428fffe0 sp=0xc0428fffd8 pc=0x457531
created by posam/protocol/usbcan.(*Channel).Start
/media/sf_GOPATH0/src/posam/protocol/usbcan/usbcan.go:242 +0x3aa
I got confused for couple of days, until the app runs with GOGC=off
.
Everything works fine except the increasing memory usage.
According to what Dave Cheney said in cgo is not Go:
C doesn’t know anything about Go’s calling convention or growable stacks, so a call down to C code must record all the details of the goroutine stack, switch to the C stack, and run C code which has no knowledge of how it was invoked, or the larger Go runtime in charge of the program.
and JimB said in stackoverflow:
Another possibility is if you’re passing a pointer to C that goes out of scope and is occasionaly GC’ed before the cgo call returns
I realize that it is possible to trigger memory corruption when using cgo.
But in the above situation, the only things required is the type CanObj
,
not any variables.
So what is the reason of this error, and how can I play well with cgo?
Here’re links about this question:
- runtime: panic only with GOGC=on and highly concurrent programs also using cgo · Issue #30276 · golang/go · GitHub
- go - Does data race happen when using cgo? - Stack Overflow
Thank you!