go runtime_error ai_generated true

panic: runtime error: cgo callback has unpinned Go pointer

ID: go/cgo-callback-gc-pin

Also available as: JSON · Markdown · 中文
80%Fix Rate
88%Confidence
0Evidence
2024-03-15First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
1.22 active
1.23 active

Root Cause

Passing a Go pointer to a C function that stores it and later calls back, but the Go memory was not pinned, causing GC to move it.

generic

中文

将Go指针传递给C函数,该函数存储了指针并在之后回调,但Go内存未固定,导致GC移动了它。

Workarounds

  1. 90% success Use `runtime.Pin` to pin the Go object before passing to C
    p := &myStruct{}
    runtime.Pin(p)
    defer runtime.Unpin(p)
    C.callback(unsafe.Pointer(p))
  2. 85% success Allocate C memory and copy data
    cMem := C.malloc(C.size_t(unsafe.Sizeof(myStruct{})))
    C.callback(cMem)
    C.free(cMem)

Dead Ends

Common approaches that don't work:

  1. Using `runtime.KeepAlive` after callback 70% fail

    KeepAlive only prevents GC before the call, does not pin during C execution.

  2. Making the pointer a global variable 50% fail

    GC can still move global pointers if not pinned.