【问题标题】:ZeroMQ assertion failed: socket handle no longer valid for some reasonZeroMQ 断言失败:套接字句柄由于某种原因不再有效
【发布时间】: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


【解决方案1】:

正如@user253751 所建议的那样,罪魁祸首似乎是应用程序中的一段特定代码关闭了相同的HANDLE 两次。我们代码中的一个严重错误,而不是 ZeroMQ!

在 Windows 上,关闭的句柄会立即被重复使用,因此在第一个 CloseHandle 之后立即打开的任何内容都有可能在第二个 CloseHandle 触发时因错误而被意外关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-22
    • 2021-07-08
    • 2016-04-26
    • 2014-03-17
    • 2018-06-02
    • 2011-10-12
    • 2019-01-10
    • 1970-01-01
    相关资源
    最近更新 更多