c语言 - 为什么在 glib 主上下文中用 zmq_poll() 替换 poll() 时出现段错误?



我正试图将zeromq集成到glib主循环中,但我不明白为什么我的程序是segfault。

以下是在运行g_main_loop_run(循环)后保证segfault的函数:

/** set poll fn to operate on zmq or unix sockets */
g_main_context_set_poll_func( g_context, (GPollFunc) zmq_poll );

考虑到zmq_pollpoll共享相同的结构,并且使用s/zmq_poll/poll/调用相同的函数也很好,我认为这会起作用。

我的代码的剥离版本仍然分段:http://paste.pocoo.org/show/568289/.

(未经测试)完整版本:http://paste.pocoo.org/show/568292/.

Stacktrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6a2bd50 in ?? ()
   from /usr/lib/libzmq.so.1
(gdb) bt
#0  0x00007ffff6a2bd50 in ?? ()
   from /usr/lib/libzmq.so.1
#1  0x00007ffff6a34b4d in zmq_getsockopt ()
   from /usr/lib/libzmq.so.1
#2  0x00007ffff6a34e1b in zmq_poll ()
   from /usr/lib/libzmq.so.1
#3  0x00007ffff6c89dc8 in ?? ()
   from /usr/lib/libglib-2.0.so.0
#4  0x00007ffff6c8a5f2 in g_main_loop_run ()
  from /usr/lib/libglib-2.0.so.0
#5  0x0000000000402978 in main (argc=1, 
argv=0x7fffffffe5e8) at server.c:229

使用编译代码(假设您安装了gstreamer和zeromq)

gcc --debug `pkg-config gstreamer-0.10 --libs` -lzmq `pkg-config gstreamer-0.10 --cflags` -o test test.c

我做错了什么?

感谢您的帮助。

编辑:使用这个函数作为我的民意测验替代:,它符合亚历山大的建议

gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
    zmq_pollitem_t ufds0[nfsd];
    int i;
    for (i = 0; i < nfsd; i++)
    {
        ufds0[i].socket = NULL;
        ufds0[i].fd = ufds[i].fd;
        ufds0[i].events = ufds[i].events;
        ufds0[i].revents = ufds[i].revents;
    }
    zmq_poll(ufds0, nfsd, timeout_);
}

老实说,我甚至不确定它是如何工作的,但我是一个C新手,不知道如何进行更自适应的自适应()。

GPollFunc回调的预期数据格式为

struct GPollFD {
#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
  gint64 fd;
#else
  gint      fd;
#endif
  gushort   events;
  gushort   revents;
};

zmq_poll的预期数据格式为

typedef struct
{
    void //*socket//;
    int //fd//;
    short //events//;
    short //revents//;
} zmq_pollitem_t;

解决方案是编写适配器并将其传递给g_main_context_set_poll_func:

gint zmq_poll_adapter(GPollFD *ufds, guint nfsd, gint timeout_)
{
    zmq_pollitem_t *ufds0 = adapt(ufds, nfsd);
    zmq_poll(ufds0, nfsd, timeout_);
}

最新更新