passing pointer between go and c rules cgo result has Go pointer

1,725 views
Skip to first unread message

Mohammad Zolfaghari

unread,
Apr 11, 2016, 1:26:06 PM4/11/16
to golang-nuts
Hi,

I am getting runtime error: cgo result has Go pointer
According to cgo-pointers is this error caused by violation of rule #2? Is the error message showing the violated rule to?
I'm saying this because I know that runtime errorcgo argument has Go pointer to Go pointer points to violation of rule #1.
Also how can I resolve this problem? the complete code exists here.

// static inline PyObject *typeAlloc(PyObject *t, Py_ssize_t n) {
//    return ((PyTypeObject *)t)->tp_alloc((PyTypeObject *)t, n);
// }
import "C"

func (t *Type) Alloc(n int64) (Object, error) {
ret := C.typeAlloc(c(t), C.Py_ssize_t(n)) // This line is causing the error
return obj2ObjErr(ret)
}

func c(obj Object) *C.PyObject {
if obj == nil {
return nil
}
return (*C.PyObject)(unsafe.Pointer(obj.Base()))
}

Ian Lance Taylor

unread,
Apr 11, 2016, 2:41:19 PM4/11/16
to Mohammad Zolfaghari, golang-nuts
On Mon, Apr 11, 2016 at 10:23 AM, Mohammad Zolfaghari <zid...@gmail.com> wrote:
>
> I am getting runtime error: cgo result has Go pointer

This error means that an exported function (a function with a //export
comment) is returning a Go pointer. That is, in the link you
mentioned, it is a violation of rule 3. The code snippet you showed
does not include any exported functions, so that is not where the
problem is coming from. The panic should give you a stack trace that
shows the problem.

Ian

Mohammad Zolfaghari

unread,
Apr 11, 2016, 5:55:01 PM4/11/16
to golang-nuts, zid...@gmail.com
Thanks for the help, At first I though this might be violation of rule #1 or #2 so I was mislead
after reading the stack trace again I found the function causing this. but I still don't know how
to resolve this problem.
stack trace:
--- FAIL: TestMethod (0.03s)
panic: runtime error: cgo result has Go pointer [recovered]
        panic: runtime error: cgo result has Go pointer

goroutine 5 [running]:
panic(0x5b35a0, 0xc82000e7c0)
        /usr/lib/go/src/runtime/panic.go:464 +0x3e6
testing.tRunner.func1(0xc82009c000)
        /usr/lib/go/src/testing/testing.go:467 +0x192
panic(0x5b35a0, 0xc82000e7c0)
        /usr/lib/go/src/runtime/panic.go:426 +0x4e9
        ??:0 +0x3a
        ??:0 +0x6f
        ??:0 +0x42
        /home/zoli/Code/go/src/github.com/limetext/gopy/lib/type.go:40 +0xd9
        /home/zoli/Code/go/src/github.com/limetext/gopy/lib/class.go:449 +0x35d
        ??:0 +0x6e
        ??:0 +0x42
github.com/limetext/gopy/lib.RunString(0x629ca0, 0x22, 0x2, 0x7fe0a499a598, 0x7fe0a48bcc08, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
        /home/zoli/Code/go/src/github.com/limetext/gopy/lib/run.go:34 +0x209
        /home/zoli/Code/go/src/github.com/limetext/gopy/lib/module_test.go:75 +0x82f
testing.tRunner(0xc82009c000, 0x8f1a08)
        /usr/lib/go/src/testing/testing.go:473 +0x98
created by testing.RunTests
        /usr/lib/go/src/testing/testing.go:582 +0x892
exit status 2
FAIL    github.com/limetext/gopy/lib    0.032s

Also the function causing this(also the complete code is here):
//export goGenericAlloc
func goGenericAlloc(t unsafe.Pointer, n C.Py_ssize_t) unsafe.Pointer {
var obj *C.PyObject

typ := newType((*C.PyObject)(t))
size := uintptr(C.var_size(c(typ), n))

if typ.IsGc() {
obj = goGcMalloc(size)
} else {
obj = goMalloc(size)
}

if obj == nil {
raise(MemoryError.ErrV(None))
return nil
}

if typ.o.tp_flags&C.Py_TPFLAGS_HEAPTYPE != 0 {
typ.Incref()
}

if typ.o.tp_itemsize == 0 {
C.GoPyObject_INIT(obj, c(typ))
} else {
C.GoPyObject_INIT_VAR(obj, c(typ), n)
}

if typ.IsGc() {
C.GoPyObject_GC_Track(obj)
}

return unsafe.Pointer(obj)
}


Ian Lance Taylor

unread,
Apr 11, 2016, 7:03:20 PM4/11/16
to Mohammad Zolfaghari, golang-nuts
On Mon, Apr 11, 2016 at 2:55 PM, Mohammad Zolfaghari <zid...@gmail.com> wrote:
>
> --- FAIL: TestMethod (0.03s)
> panic: runtime error: cgo result has Go pointer [recovered]
> panic: runtime error: cgo result has Go pointer

> Also the function causing this(also the complete code is here):
> //export goGenericAlloc
> func goGenericAlloc(t unsafe.Pointer, n C.Py_ssize_t) unsafe.Pointer {

This is an exported function. It may not return a Go pointer. A Go
pointer is a pointer to memory that has been allocated by the Go
runtime.


> if typ.IsGc() {
> obj = goGcMalloc(size)
> } else {
> obj = goMalloc(size)
> }

This is where the return value is set. If you look at those
functions, you will see that this sets obj to memory allocated by the
Go runtime; specifically, these functions call _goMalloc which calls
make. The make function returns a Go pointer.

You need to change this code to allocate memory using C.malloc, or
some Python function, instead.

Ian
Reply all
Reply to author
Forward
0 new messages