【发布时间】:2015-03-11 05:44:42
【问题描述】:
我正在使用 ZMQ (zmq.hpp) 编写 MFC 应用程序的扩展。当我试图从应用程序中卸载我的 DLL 时,zmq_ctx_destroy() 函数会永远挂起。
我找到了a similar issue,但没有答案。
我尝试调试它,发现它在第一行的函数 zmq::thread_t::stop() 中停止:
DWORD rc = WaitForSingleObject (descriptor, INFINITE);
即使没有发送任何内容,它也会挂起。简化后的代码如下所示:
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.connect(ENDPOINT.c_str());
套接字和上下文在离开作用域时被破坏。
调用栈:
libzmq-v100-mt-gd-4_0_4.dll! zmq::thread_t::stop() Line 56 + 0x17 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::~select_t() Line 57 + 0x13 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::select_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::~io_thread_t() Line 39 + 0x37 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::io_thread_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::~ctx_t() Line 82 + 0x49 bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::`scalar deleting destructor'() + 0x2c bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq::ctx_t::terminate() Line 153 + 0x3d bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_term(void * ctx_) Line 171 + 0xa bytes C++
libzmq-v100-mt-gd-4_0_4.dll! zmq_ctx_destroy(void * ctx_) Line 242 C++
DataReader.dll! zmq::context_t::close() Line 309 + 0xe bytes C++
DataReader.dll! zmq::context_t::~context_t() Line 303 C++
MFC 应用程序具有运行专门创建的 DLL 的机制。此 DLL 基于 CWinApp,InitInstance 成员函数中的所有 DLL 特定的初始化代码和 ExitInstance 中的终止代码。所以this JIRA issue不应该是这样。
几天后,我发现该应用程序还依赖套接字作为 ZMQ。因此,在其生命结束时,ZMQ 上下文正在等待关闭进程中所有打开的套接字,但 MFC 应用程序继续使用其打开的套接字。这就是 zmq_ctx_destroy() 函数永远挂起的原因。
【问题讨论】:
-
这是 ZMQ 或 MFC 的错误报告,恕我直言,这不是问题。无论如何,两者的资源都是可用的,因此请随时调试问题。我认为 ZMQ 使用了一些全局变量,这些是我要研究的,它们也会在其他环境中引起问题。
-
DllMain entry point: "警告 可以在 DLL 入口点安全执行的操作有很大的限制。请参阅 General Best Practices 了解特定的 Windows API在 DllMain 中调用不安全。”
标签: c++ sockets dll mfc zeromq