go - CGO 指针检查中的已知实现错误

标签 go cgo

根据 CGO 的文档( https://pkg.go.dev/cmd/cgo ),在实现中有一个已知的错误:

Note: the current implementation has a bug. While Go code is permitted to write nil or a C pointer (but not a Go pointer) to C memory, the current implementation may sometimes cause a runtime error if the contents of the C memory appear to be a Go pointer. Therefore, avoid passing uninitialized C memory to Go code if the Go code is going to store pointer values in it. Zero out the memory in C before passing it to Go.


我在 GitHub 的问题跟踪器中寻找过这个,但在那里找不到。有人可以详细说明为什么会发生这种情况吗?运行时如何在未初始化的 C 内存中找到 Go 指针?
例如。假设我将一个未初始化的 char 数组从 C 传递给 Go 函数,运行时如何解释该内存中的 Go 指针?
此外,“如果 Go 代码将在其中存储指针值”部分让我感到困惑。为什么以后使用这个内存很重要?

最佳答案

I looked for this in the issue tracker at GitHub but can't find it there.


此评论所指的错误是 https://golang.org/issue/19928 ,这当然不容易找到。 😅

Could someone please elaborate on why this might happen? How does the runtime find Go pointers in uninitialized C memory?


在垃圾收集周期的某些部分,收集器打开“write barrier ”用于写入Go堆中的指针,记录之前存储的指针值,以确保在GC扫描过程中不会遗漏。
这里的错误是写屏障有时也会为 Go 堆外的指针记录先前存储的指针值。如果该值看起来像 Go 指针,垃圾收集器可能会尝试递归扫描它,如果它实际上不是有效指针,则可能会崩溃。

Eg. let's say I am passing an uninitialized char array to a Go function from C, how can the runtime interpret a Go pointer in this memory?


如果传递给 Go 的未初始化数据的类型不包含任何指针,则不应发生此错误。所以对于 char尤其是数组,无论哪种方式,您都应该没问题。

Also, the "if the Go code is going to store pointer values in it" part confuses me. Why does later use of this memory matter?


编译器在指针类型的存储指令中插入写屏障。如果 Go 程序不存储指针,那么编译器不会发出任何写屏障,也不会触发写屏障中的 bug。

关于go - CGO 指针检查中的已知实现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68361435/

相关文章:

c - 尝试在 Windows 上使用 cuda

macos - 无法打印到标准输出

Golang 模板不渲染 html

http - 在golang中测试http.Pusher和推送功能

node.js - 如何生成 HMAC

c - 为什么 dlsym 在 cgo 中产生的结果与在 c 中产生的结果不同?

go - 在 Golang 项目中正确包含 C 库(按源代码)

go - 迭代结构中的字符串字段

xml - 获取原始元素表示,包括开始和结束标签

c - 如何比较 Go 中的 errno?