zmq_ctx_destroy() 在 MFC dll 中挂起

Posted

技术标签:

【中文标题】zmq_ctx_destroy() 在 MFC dll 中挂起【英文标题】:zmq_ctx_destroy() hangs in MFC dll 【发布时间】: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 中调用不安全。” 【参考方案1】:

此类情况的解决方案(当应用程序也使用套接字并且您需要添加一些基于 ZMQ 的功能时)。 创建一个新进程。这个过程将创建一个 ZMQ 上下文并发送/接收所有消息。来自 dll 的数据可以通过 Windows 消息或共享内存传递给该进程。

【讨论】:

这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post。 @TonyHopkinson 为什么这没有提供问题的答案? 它读起来像评论,或者是对您自己问题的扩展。您可能很清楚,如果是这样,请接受它,但是看起来您最初做错了,或者这是一种解决方法。想想未来的 SO 用户。 那么,我应该删除我的答案吗?我对问答做了一些改动。 没有伙伴。作为审稿人,它被扔给了我,我遇到了一些问题,Craig S Anderson 也是如此。你已经对它进行了足够的改进,以至于我的反对意见看起来已经过时了,所以其他未来的评论者不太可能投票赞成删除。需要我们两个以上,否则它已经消失了。即使这样,您也有机会解决问题,审阅者会收到重新打开的请求。

以上是关于zmq_ctx_destroy() 在 MFC dll 中挂起的主要内容,如果未能解决你的问题,请参考以下文章

打开我的项目 exe 后缺少 mfc120d.dll

MFC 多线程与 delete[] , d​​bgheap.c

找不到 c:\windows\system32\mfc100d.dll

将类从 MFC 移植到 C++ 控制台应用程序。使用 /MD[d](CRT dll 版本)构建 MFC 应用程序需要

MFC CRect

Release 编译需要 mfc140ud.dll 和 vcruntime140d.dll