pebbe / zmq4

A Go interface to ZeroMQ version 4
BSD 2-Clause "Simplified" License
1.17k stars 163 forks source link

Argument has Go pointer to Go pointer when using Go 1.6 #68

Closed napsy closed 8 years ago

napsy commented 8 years ago

I tested the latest zmq4 code using Go 1.6 beta1 and this is what I get

panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 22 [running]:
github.com/pebbe/zmq4._cgoCheckPointer0(0x8c0fa0, 0xc820164a34, 0x0, 0x0, 0x0, 0x7fb1680034b0)
    ??:0 +0x4d
github.com/pebbe/zmq4.(*Socket).SendBytes(0xc820152bd0, 0xc820164a34, 0x1f, 0x40, 0x2, 0x4, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/zmq4.go:770 +0x3d1
github.com/pebbe/zmq4.(*Socket).sendMessage(0xc820152bd0, 0x0, 0xc8201b9ca0, 0x1, 0x1, 0x4, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/utils.go:66 +0x4b4
github.com/pebbe/zmq4.(*Socket).SendMessage(0xc820152bd0, 0xc8201b9ca0, 0x1, 0x1, 0xc820158840, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/utils.go:18 +0x56

I tried to modify socket.SendBytes by getting the []byte header and the send only the bytes but it resulted in the same error:

hdr := (*reflect.SliceHeader)(unsafe.Pointer(&d))
size, err := C.zmq_send(soc.soc, unsafe.Pointer(hdr.Data), C.size_t(len(data)), C.int(flags))

The []byte slice in question is nothing but a serialized map[string]string.

pebbe commented 8 years ago

What is the code you tested with?

napsy commented 8 years ago

It goes something like this:

import (
    msgpack "gopkg.in/vmihailenco/msgpack.v2"
    "github.com/pebbe/zmq4"
)
...
// marshal using msgpack
data, err := msgpack.Marshal(map[string]string{"hello":"world"})
parts := [][]byte{[]byte("aRoute"), data}
publisher.SendMessage(parts)
pebbe commented 8 years ago

I don't get this panic in go1.5.2 I also don't get this panic in Go 1.6 when I change the code to this:

data :=  []byte("\x81\xa5hello\xa5world")
parts := [][]byte{[]byte("aRoute"), data}
publisher.SendMessage(parts)

Perhaps a bug in Go 1.6?

pebbe commented 8 years ago

Full working example:

package main

import (
    zmq "github.com/pebbe/zmq4"
    msgpack "gopkg.in/vmihailenco/msgpack.v2"

    "fmt"
    "log"
)

func main() {

    pub, err := zmq.NewSocket(zmq.PUB)
    if err != nil {
        log.Fatal(err)
    }
    err = pub.Bind("tcp://127.0.0.1:9997")
    if err != nil {
        log.Fatal(err)
    }

    data, err := msgpack.Marshal(map[string]string{"hello": "world"})
    if err != nil {
        log.Fatal(err)
    }
    // uncommenting the next line makes the panic disappear
    //data = []byte("\x81\xa5hello\xa5world")

    parts := [][]byte{[]byte("aRoute"), data}

    n, err := pub.SendMessage(parts)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(n)
}
napsy commented 8 years ago

I tried your example again with 1.6 beta1 (linux/amd64) and I get the same panic:

panic: runtime error: cgo argument has Go pointer to Go pointer

goroutine 1 [running]:
github.com/pebbe/zmq4._cgoCheckPointer0(0x505400, 0xc820012104, 0x0, 0x0, 0x0, 0x2351170)
    ??:0 +0x4d
github.com/pebbe/zmq4.(*Socket).SendBytes(0xc8200148a0, 0xc820012104, 0xd, 0x40, 0x0, 0x6, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/zmq4.go:769 +0x16b
github.com/pebbe/zmq4.(*Socket).sendMessage(0xc8200148a0, 0x0, 0xc82004be70, 0x1, 0x1, 0x6, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/utils.go:66 +0x4b4
github.com/pebbe/zmq4.(*Socket).SendMessage(0xc8200148a0, 0xc82004be70, 0x1, 0x1, 0xc82000e4c0, 0x0, 0x0)
    /home/napsy/git/koala2/src/github.com/pebbe/zmq4/utils.go:18 +0x56
main.main()
    /home/napsy/git/koala2/test.go:29 +0x622

It seems that this is indeed a go1.6 bug

pebbe commented 8 years ago

@napsy I tested with Go tip, and it is working fine. Can you test your code too?

napsy commented 8 years ago

@pebbe yes on go tip it works, closing.