2017-11-11 11:24
浏览 95


I'm currently writing a Go wrapper around a C library. That C library uses opaque struct pointers to hide information across the interface. However, the underlying implementation stores size_t values in there. This leads to runtime errors in the resulting program. A minimum working example to reproduce the problem looks like this:


package main

#include "stddef.h"
// Create an opaque type to hide the details of the underlying data structure.
typedef struct HandlePrivate *Handle;

// In reality, the implementation uses a type derived from size_t for the Handle.
Handle getInvalidPointer() {
    size_t actualHandle = 1;
    return (Handle) actualHandle;
import "C"

// Create a temporary slice containing invalid pointers.
// The idea is that the local variable slice can be garbage collected at the end of the function call.
// When the slice is scanned for linked objects, the GC comes across the invalid pointers.
func getTempSlice() {
    slice := make([]C.Handle, 1000000)
    for i, _ := range slice {
        slice[i] = C.getInvalidPointer()

func main() {

Running this program will lead to the following error

runtime: writebarrierptr *0xc42006c000 = 0x1
fatal error: bad pointer in write barrier
[...stack trace omitted...]

Note that the errors disappear when the GC is disabled by setting the environment variable GOGC=off.

My question is which is the best way to solve or work around this problem. The library stores integer values in pointers for the sake of information hiding and this seems to confuse the GC. For obvious reasons I don't want to start messing with the library itself but rather absorb this behaviour in my wrapping layer.

My environment is Ubuntu 16.04, with gcc 5.4.0 and Go 1.9.2.

Documentation of cgo

图片转代码服务由CSDN问答提供 功能建议

我目前正在用C库编写Go包装器。 该C库使用不透明的结构指针来隐藏整个接口中的信息。 但是,底层实现在其中存储size_t值。 这会导致结果程序中出现运行时错误。 重现此问题的最小工作示例如下:

main.go \ n

 / * 
#include“ stddef.h” 
typedef struct HandlePrivate * Handle  ; 
Handle getInvalidPointer(){
 size_t actualHandle = 1; 
 * /  
import“ C” 
func getTempSlice(){
 slice:= make([] C.Handle,1000000)
 for i,_:= range slice {
 slice [  i] = C.getInvalidPointer()
func main(){

Runn 执行此程序将导致以下错误

 运行时:writebarrierptr * 0xc42006c000 = 0x1 
 [...堆栈跟踪被省略。  。] 

请注意,通过设置环境变量 GOGC = off 禁用GC时,错误消失了。 \ n

我的问题是解决或解决此问题的最佳方法。 该库将整数值存储在指针中,以便隐藏信息,这似乎使GC感到困惑。 出于明显的原因,我不想开始弄乱库本身,而是想在我的包装层中吸收这种行为。

我的环境是Ubuntu 16.04,带有gcc 5.4.0和Go 1.9 .2。


  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 邀请回答

1条回答 默认 最新

相关推荐 更多相似问题