pebbe / zmq4

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

Segfaults with zeromq-4.1.5, but not 4.1.6 with Go 1.9 #117

Open bbailey1024 opened 6 years ago

bbailey1024 commented 6 years ago

Currently running Go 1.9 and zeromq-4.1.5 and I'm running into invalid memory address or nil pointer dereference errors.

The following code results in the following errors.

package main

import (
    "fmt"
    zmq "github.com/pebbe/zmq4"
)

func main() {

    // Create Worker Subscriber
    workerSub, _ := zmq.NewSocket(zmq.SUB)
    defer workerSub.Close()
    workerSub.Bind("tcp://127.0.0.1:7272")
    workerSub.SetSubscribe("")

    for {
        log, _ := workerSub.Recv(0)
        fmt.Println(log)
    }
}
$ ldd zmq-sub
    linux-vdso.so.1 (0x00007ffd309ed000)
    libzmq.so.5 => /usr/lib/libzmq.so.5 (0x00007fa5bb49c000)
    libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fa5bb27e000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fa5baec7000)
    libsodium.so.18 => /usr/lib/libsodium.so.18 (0x00007fa5bac59000)
    libpgm-5.2.so.0 => /usr/lib/libpgm-5.2.so.0 (0x00007fa5baa0c000)
    librt.so.1 => /usr/lib/librt.so.1 (0x00007fa5ba804000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fa5ba47d000)
    libm.so.6 => /usr/lib/libm.so.6 (0x00007fa5ba131000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fa5b9f1a000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa5bb707000)
$ ls -la /usr/lib/libzmq.so.5
lrwxrwxrwx 1 root root 15 Oct 18 17:27 /usr/lib/libzmq.so.5 -> libzmq.so.5.0.1
$ ./zmq-sub
panic: runtime error: invalid memory address or nil pointer dereference
    panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x4a4486]

goroutine 1 [running]:
github.com/pebbe/zmq4.(*Socket).Close(0x0, 0xc420010320, 0x4e166f)
    /path/to/go/src/github.com/pebbe/zmq4/zmq4.go:821 +0x26
panic(0x4c3840, 0x753a90)
    /usr/lib/go/src/runtime/panic.go:491 +0x283
github.com/pebbe/zmq4.(*Socket).Bind(0x0, 0x4e28a3, 0x14, 0x0, 0x0)
    /path/to/go/src/github.com/pebbe/zmq4/zmq4.go:846 +0x38
main.main()
    /path/to/go/src/zmq_test1/zmq-sub.go:13 +0x80

If I upgrade to zeromq 4.1.6, remove and reinstall github.com/pebbe/zmq4 the error goes away and the program works as expected. We currently have 4.1.5 deployed in production and it's not trivial at this time to upgrade to 4.1.6.

activeshadow commented 6 years ago

I'm seeing this too w/ 4.1.4, but at a different spot in the pebbe/zmq4 library. Haven't been able to test w/ 4.1.6 at all. Any ideas on this?

activeshadow commented 6 years ago

Nevermind... mine was a different issue (stupidity on my part).

antoniomtz commented 5 years ago

I'm getting the same issue with any version of ZeroMQ and Go 1.12 Any ideas?

anoop54 commented 4 years ago

@antoniomtz any update?

chrbsg commented 2 years ago

Just a hint, if you are getting segfaults then note that ZeroMQ is not thread-safe:

Don’t share ZeroMQ sockets between threads. ZeroMQ sockets are not threadsafe. Technically it’s possible to migrate a socket from one thread to another but it demands skill. The only place where it’s remotely sane to share sockets between threads are in language bindings that need to do magic like garbage collection on sockets. - https://zguide.zeromq.org/docs/chapter2/#Multithreading-with-ZeroMQ

This constraint is easy to violate if you are using Goroutines. To avoid this, you'll need to either use explicit locking around zmq operations, or, preferably, put all zmq operations in a single goroutine and use channels to send data to/from other goroutines.

jdemeyer commented 1 year ago

Just a hint, if you are getting segfaults then note that ZeroMQ is not thread-safe:

Shouldn't there be like a huge warning on the README then, especially since it's so easy to do non-thread-safe things in Go?

I am currently debugging random crashes involving zeromq and I know now that I'm violating this requirement. So I might have to redesign my application around the requirement that zeromq sockets must be local to one goroutine, locked with runtime.LockOSThread().