zeromq / libzmq

ZeroMQ core engine in C++, implements ZMTP/3.1
https://www.zeromq.org
Mozilla Public License 2.0
9.62k stars 2.35k forks source link

Segmentation fault by socket type ZMQ_SUB with static build #4535

Closed rhymerjr closed 1 year ago

rhymerjr commented 1 year ago

Unfortunately I cannot understand why segfault is happening when building my program as static! Segfault happens when the call zmq_recv is reached!

The build command: g++ -g -static -std=c++17 main.cpp -o main.bin -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -ldl /usr/local/lib/libzmq.a

But everythig is OK If i'm building it using the dynamic libraries: g++ -g -std=c++17 main.cpp -o main.bin -lzmq

What could be the problem with static build?

Environment

Minimal test code / Steps to reproduce the issue

#include <iostream>
#include <string>
#include <cstring>
#include <zmq.h>
#define BSIZE 512
void* context;
void* socket;
int main(int argc, char **argv)
{
    printf("dbg - 0\n");
    const std::string connstr = "tcp://127.0.0.1:5678";
    printf("dbg - 1\n");
    if (NULL==(context=zmq_ctx_new()))
    {
        printf("ERROR - Failed to create context(%d:%s)!\n",errno,zmq_strerror(errno));
        return -1;
    }
    printf("dbg - 2\n");
    if (NULL==(socket=zmq_socket (context, ZMQ_SUB)))
    {
        printf("ERROR - Failed to create socket!(%d:%s)\n",errno,zmq_strerror(errno));
        return -1;
    }
    printf("dbg - 3\n");
    if (-1==zmq_setsockopt (socket, ZMQ_SUBSCRIBE, "", 0))
    {
        printf("ERROR - Failed to set socket option(SUBSCRIBE)!(%d:%s)\n",errno,zmq_strerror(errno));
    }
    printf("dbg - 4\n");
    if (0!=zmq_connect (socket, connstr.c_str()))
    {
        printf("ERROR - Failed to connect (%d:%s)\n",errno,zmq_strerror(errno));
        return -1;
    }
    printf("dbg - 5\n");
    while (1)
    {
        printf("dbg - 6\n");
        char buf [BSIZE];
        printf("dbg - 7\n");
        memset (buf,'\0',BSIZE);
        printf("dbg - 8\n");
        int nbytes = zmq_recv (socket, buf, BSIZE, 0);
        printf("dbg - 9\n");
        if (nbytes>0)
        {
            printf("dbg - 10\n");
            printf("'%d' bytes received: '%s'\n",nbytes,buf);
        }
        else
        {
            printf("dbg - 11\n");
            printf("value of nbytes '%d'\n",nbytes);
        }
    }
    printf("dbg - 12\n");
    if (0!=zmq_disconnect (socket, connstr.c_str()))
    {
        printf("ERROR - Failed to disconnect (%d:%s)\n",errno,zmq_strerror(errno));
    }
    if (0!=zmq_close(socket))
    {
        printf("ERROR - Failed to close socket (%d:%s)\n",errno,zmq_strerror(errno));
    }
    if (0!=zmq_ctx_term(context))
    {
        printf("ERROR - Failed to terminate context (%d:%s)\n",errno,zmq_strerror(errno));
    }
    return 0;
}

What's the actual result? (include assertion message & call stack if applicable)

`Reading symbols from ./main.bin... (gdb) run Starting program: /home/dev/src/testings/pubsub/main.bin [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". dbg - 0 dbg - 1 dbg - 2 [New Thread 0x7ffff7ff8700 (LWP 1649)] [New Thread 0x7ffff77f7700 (LWP 1650)] dbg - 3 dbg - 4 dbg - 5 dbg - 6 dbg - 7 dbg - 8

Thread 3 "ZMQbg/IO/0" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff77f7700 (LWP 1650)] 0x00000000006847b8 in socket () (gdb) bt

0 0x00000000006847b8 in socket ()

1 0x0000000000470185 in zmq::tcp_opensocket (address=0x6a6c00 "127.0.0.1:5678", options=..., local=local_@entry=false,

fallback_to_ipv4_=fallback_to_ipv4_@entry=true, out_tcp_addr_=0x7ffff00013a0) at src/tcp.cpp:371

2 0x0000000000470705 in zmq::tcp_connecter_t::open (this=0x7ffff0000b60) at src/tcp_connecter.cpp:185

3 0x0000000000470985 in zmq::tcp_connecter_t::start_connecting (this=0x7ffff0000b60) at src/tcp_connecter.cpp:139

4 0x00000000004273e3 in zmq::object_t::processcommand (this=0x7ffff0000b60, cmd=...) at src/object.cpp:86

5 0x0000000000423414 in zmq::io_thread_t::in_event (this=0x6a5630) at src/io_thread.cpp:91

6 0x00000000004223e0 in zmq::epoll_t::loop (this=0x6a5be0) at src/epoll.cpp:210

7 0x000000000043fa53 in threadroutine (arg=0x6a5c38) at src/thread.cpp:256

8 0x0000000000408cc7 in start_thread (arg=) at pthread_create.c:477

9 0x00000000005b261f in clone ()

(gdb)`

What's the expected result?

Do not segfault when building as static

coredump.tar.gz

rhymerjr commented 1 year ago

I found that it was a scope issue with the variables: void context; void socket; Don't know exactly what was the problem but moved these variables into the main function has solved the problem!