防止、避免或绕过应用程序崩溃(AppCrash)

4
我们遇到了一个看似随机的AppCrash问题,Windows会接管进程并关闭它,给出一些包括NTDLL.dll、StackHash、User32.dll等信息的神秘调试报告。对这些模块和报告中的信息进行超过一年的研究,我们得到的信息比之前少得多。我们能做到的最好的事情就是将其缩小到我们的应用程序使用与通过TCP/IP通信的硬件交互的DLL上。我们无法控制这个外部库,必须使用它,并且考虑到问题是随机的(我们无法在自己的端口复制它,在PC重新启动时解决),我们似乎陷入了困境。
问题在于我们的应用程序需要在不受人为监控的仪器上运行24/7。我需要检测我们的应用程序何时崩溃,并发出重新启动整个应用程序的命令。问题是如何检测AppCrash;没有异常在应用程序内生成(AppCrash是外部应用程序),也没有任何日志记录表明程序正在关闭。
我们想要做的是运行一个服务来检查应用程序是否在运行,如果没有,则发出重新启动系统的命令。然而,当AppCrash对话框显示时,它会使进程继续运行。
有没有办法防止这些AppCrash通知、绕过它们或至少先关闭程序?请不要指向stackhash.com或使用MS错误报告;这些设备无法连接到互联网。我们也不能修复我们正在使用的DLL中的任何错误(OEM供应商不合作)。

你的应用程序崩溃了还是你依赖的另一个应用程序或者与之交互的应用程序崩溃了? - Jalal Said
我的应用程序崩溃了,但是它是由于在一个P/Invoke DLL中发生了非常严重的问题造成的,可能是访问冲突或者操作系统无法恢复的其他问题。 - drharris
关闭 WER,如果没有人在那里,显示对话框也没意义。请在超级用户网站上咨询。 - Hans Passant
3个回答

6

一种方法可以是,让应用程序定期向另一个服务发送消息,告知其正常运行,而不是尝试检测崩溃。使用IPC,您可以每秒向监控服务发送一条心跳消息。


这实际上对于这种情况并不是一个坏策略。我之前考虑过这个方案,但因为有时候会有人在设备上操作,并且可能会优雅地关闭软件来处理它,所以我拒绝了它。但是,我可以轻松地在程序打开/关闭时发送状态来检测这种情况,并在手动关闭时不执行它。 - drharris
考虑到您的限制,这似乎是最佳方法。我能想到的唯一其他解决方案是定期搜索窗口列表以查找该错误消息窗口的辅助服务。 - Nathanael
最终,我认为这是我现在必须采取的方法。 - drharris
2
要关闭阻止进程退出的Windows消息,请编辑注册表中的HKLM\Software\Microsoft\Windows\Windows Error Reporting,并将Disabled的值设置为true-请参见http://msdn.microsoft.com/en-us/library/bb513638%28v=vs.85%29.aspx。 - Yahia

3
您可以创建一个与DLL交互的包装器应用程序,并将您的应用程序作为单独的进程启动该包装器并仅与包装器应用程序通信(例如通过MemoryMappedFile和命名Mutex)。
这样,当发生AppCrash时,您的应用程序不会直接受到影响(只有包装器被终止),它可以自动采取您认为必要的措施(例如让对话框消失和/或使用Process.Kill摆脱它...)。
您甚至可以将该包装器制作成Windows服务,然后在故障时配置自动重启(在MMC / Services中)。
另一点是设置操作系统在这种情况下自动重新启动(如果将其归类为系统错误,则可以配置此类行为)。
编辑-根据评论提供一些关于MemoryMappedFile信息的链接:

这是我的第一个想法,它可能提供更好的恢复。问题在于实时性质。那个DLL恰好是一个非常核心的组件,大约95%的工作都在一个非常紧密的循环中不断调用该DLL。将其外包给另一个应用程序并添加通信层对于我们需要做的事情来说是太多的开销。如果没有那个障碍,这将是我最喜欢的可能解决方案。 - drharris
我会尝试一下 - 我们之前做过类似的东西,但在性能方面我非常怀疑,但是在 .NET 4 中使用 MemoryMappedFile 后,我们并没有遇到太多问题 - 性能非常高(特别是当它不由实际文件支持时)...你甚至可以将处理逻辑中最关键的部分直接放入包装器中,并允许包装器在必要时与你的“主机”应用程序通信... - Yahia
我还没有仔细研究MemoryMappedFile,所以我会去看一下。这将是我最喜欢的方法,希望我能让它正常工作。 - drharris
谢谢提供额外的链接。我会进一步探索,因为我认为这是最适合长期使用的设计。不幸的是,这个迭代过程中我有一个紧迫的时间限制,所以现在我只能选择上面的答案。希望在它进行得太远之前我有足够的时间重新审视它。 - drharris
要关闭阻止进程退出的Windows消息,请编辑注册表HKLM\Software\Microsoft\Windows\Windows Error Reporting\并将Disabled的值设置为true-请参见msdn.microsoft.com/en-us/library/bb513638%28v=vs.85%29.aspx。 - Yahia

0

请参考以下建议: http://forums.techguy.org/windows-7/1032392-solved-all-browsers-crashing-windows.html

在管理员控制台中:

Reset WINSOCK entries to installation defaults: netsh winsock reset catalog
Reset IPv4 TCP/IP stack to installation defaults: netsh int ipv4 reset reset.log
Reset IPv6 TCP/IP stack to installation defaults: netsh int ipv6 reset reset.log

这解决了我在Firefox和Chrome上遇到的相同的stackhash问题。它似乎是一般的TCP/IP解析,可能也可以解决您应用程序的TCP/IP问题。

我猜测这些设置可能出了点问题 - 我的机器上有pcap和其他工具,所以可能会发生冲突?不知道。您是否调整过网络堆栈或网卡设备设置?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接