我使用zmq版本4.2.2。我的程序因调用zmq_abort()
而调用abort()
而崩溃。根据堆栈跟踪,如果我理解正确,则从zmq_abort()
调用src/socket_poller.cpp:54
。但是,该行是函数定义的开头:
zmq::socket_poller_t::~socket_poller_t ()
该函数没有直接调用zmq_abort()
或任何可以调用它的断言宏。在整个文件中,zmq_abort()
没有多少断言或任何直接调用。但是,堆栈跟踪中的其他行似乎与github中的源代码匹配:
https://github.com/zeromq/libzmq/blob/v4.2.2/src/socket_poller.cpp#L54
执行如何以zmq_abort()
结束?
堆栈跟踪的开始:
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7f12cc9d4700 (LWP 23680))]
(gdb) where
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f12ce123415 in __GI_abort () at abort.c:90
#2 0x00007f12ce8db9c9 in zmq::zmq_abort (errmsg_=<optimized out>) at ../zeromq-4.2.2/src/err.cpp:87
#3 0x00007f12ce918cbe in zmq::socket_poller_t::~socket_poller_t (this=0x7f12c8004150,
__in_chrg=<optimized out>) at ../zeromq-4.2.2/src/socket_poller.cpp:54
#4 0x00007f12ce91793a in zmq_poller_destroy (poller_p_=0x7f12cc9d2af8)
at ../zeromq-4.2.2/src/zmq.cpp:1236
#5 0x00007f12ce917e14 in zmq_poller_poll (timeout_=<optimized out>, nitems_=2, items_=0x1)
at ../zeromq-4.2.2/src/zmq.cpp:854
#6 zmq_poll (items_=items_@entry=0x7f12cc9d2c20, nitems_=nitems_@entry=2, timeout_=timeout_@entry=5000)
at ../zeromq-4.2.2/src/zmq.cpp:866
答案 0 :(得分:1)
zmq_abort()
的析构函数中的断言宏调用了 signaler_t
:
https://github.com/zeromq/libzmq/blob/v4.2.2/src/signaler.cpp#L143。 signaler_t
对象是socket_poller_t
的成员。我不确定为什么对析构函数的调用没有显示在堆栈跟踪中。
我试图不直接(直接)询问我的代码有什么问题,因为提供代码示例是不可行的,但我会提到原来是文件描述符在另一个线程中错误地关闭了两次。在两个关闭操作之间,zmq_poll()创建了一个socket_poller_t
对象。 signaler_t
的构造函数打开了eventfd
,这与之前关闭的fd(数字)相同。然后,另一个线程再次关闭相同的fd,导致析构函数在close()上获取EBADF并调用zmq_abort()
。