【发布时间】:2021-05-18 12:40:20
【问题描述】:
获得了一个使用 ZeroMQ 的 Windows 10 c++ 程序,该程序由于断言失败而经常在同一组计算机上中止。
assert 语句深埋在libzmq 代码中。
在其他机器上,相同的程序运行良好,没有这些问题(但平心而论,这是使用不同的操作系统版本号和程序配置)。
断言失败似乎是因为内部zeromq(基于套接字和/或管道)连接/句柄意外关闭。
什么可能导致这样的事情?
更多信息:
断言失败似乎与 ZeroMQ 用于内部信令的通道/邮箱有关。在旧版本的库中,这适用于多个环回 TCP 套接字,而现代版本依赖于涉及 IOCP(I/O 完成端口)的解决方案。
这是一个长期存在且可能相关的问题,原作者本人谈到了发生在他身上的类似崩溃:
https://github.com/zeromq/libzmq/issues/1108
使用我们应用程序的崩溃转储,我看到导致assert 语句的堆栈跟踪通常发生在尝试从套接字(或套接字文件描述符?)读取之后的某个时间点。读取或接收操作失败,然后库出现紧急情况。
所以,突然一个套接字句柄似乎不再有效。我看到的错误示例是“资源暂时不可用”和“无效的句柄/参数”之类的错误。
会不会是某物或某人强行为我们关闭了套接字? 什么可能导致这种行为?
旧版本的 zeromq (4.0.10) 和现代版本 (4.3.5) 都会发生这种情况。这让我相信,如果这些不同的实现以大致相同的方式失败,那么问题就出在其他地方。
当试图重现该问题时,我可以通过手动强制关闭 ZeroMQ 与TCPView 一起使用的内部 TCP 连接来触发 4.0.x 的类似断言失败。由此产生的断言失败是即时的,并且故障转储看起来与在野外发生的情况相同。
但现代版本似乎没有使用环回套接字,所以我无法关闭那里的“私人”连接。也许他们正在使用管道或 unix 样式的套接字(我听说现在可以在 Windows 10 上使用)。
暂时我认为短暂端口耗尽是所有这些麻烦的原因,但仅此一点对我来说没有意义:我不希望操作系统强制关闭现有连接,现有连接应该继续工作。你会认为只有新的连接会失败。
【问题讨论】:
-
可能是您的程序关闭了垃圾句柄,有时还关闭了属于 ZeroMQ 的有效句柄
-
有趣的见解!现在这个程序没有垃圾收集器,但理论上仍然可能有代码——在同一个进程中——错误地关闭句柄。
-
Garbage 不是garbage-collected,是废话,乱码,可能是因为未初始化的变量
-
啊,是的,对不起 - 我误读了您的评论。你是对的,如果数字在这些机器上而不是在其他机器上以某种方式神奇地对齐(墨菲!),确实可能是这种情况。
-
这更像是一个错误报告的主题,而不是 SO 的编程问题。确实,如果您设法在不以任何方式滥用 API 的情况下触发该断言,那么将示例程序添加到现有的或者可能是新的错误报告中。
标签: windows sockets networking zeromq