预防、避免或绕过 AppCrash

Posted

技术标签:

【中文标题】预防、避免或绕过 AppCrash【英文标题】:Preventing, Avoiding, or Bypassing AppCrash 【发布时间】:2011-10-30 02:41:48 【问题描述】:

我们得到一个看似随机的 AppCrash,实际上是 windows 接管进程并关闭它,给出一些神秘的调试报告,其中包括 NTDLL.dll、StackHash、User32.dll 等内容。研究报告中的这些模块和信息一年多以来,我们所掌握的信息几乎没有。我们所能做的最好的事情就是将其缩小为我们的应用程序用来与通过 TCP/IP 通信的硬件进行交互的 DLL。我们无法控制这个外部库,必须使用它,并且考虑到问题是随机的(我们无法复制,在 PC 重启时自行解决),我们似乎被它困住了。

问题是我们的应用程序需要在不受人类监控的仪器上 24/7 全天候运行。我需要检测我们的应用程序何时崩溃,并向整个事物发出重启命令。问题是检测到 AppCrash;应用程序内部不会产生异常(AppCrash 在应用程序外部),并且没有多少日志记录会产生任何程序正在关闭的指示。

我们想要做的是运行一个服务来检查应用程序是否正在运行,如果没有,它会发出重新启动命令来重新启动系统。但是,当 AppCrash 对话框显示时,它会让进程继续运行。

有没有办法阻止这些 AppCrash 通知、绕过它们或将它们设置为至少先关闭程序?请不要指向 stackhash.com 或使用 MS 错误报告;这些设备不支持互联网。我们也无法修复我们正在使用的 DLL 中的任何错误(OEM 供应商不合作)。

【问题讨论】:

是您的应用程序崩溃了,还是您依赖的另一个应用程序或您的应用程序正在与之交互? 我的应用程序崩溃了,但它是由 pinvoked DLL 中发生的非常糟糕的事情引起的,可能是访问冲突或操作系统无法恢复的事情。 只要关掉 WER,如果没有人,就没有必要显示对话框。向超级用户询问 【参考方案1】:

一种方法可能是让应用定期告诉另一个服务它还活着并且运行良好,而不是尝试检测它何时崩溃。使用 IPC,您可以每秒向监控服务发送一次心跳消息。

【讨论】:

对于这种情况,这实际上是一个不错的策略。我之前曾考虑过这一点,但由于有时有人在设备上,并且可能会优雅地关闭软件以进行处理,因此拒绝了它。但是,我可以轻松地在程序打开/关闭时发送状态来检测这种情况,而在手动关闭时不这样做。 考虑到您的限制,这似乎是最好的方法。我能想到的唯一其他解决方案是让帮助服务定期在窗口列表中搜索该错误消息窗口。 最后,我认为这是我现在必须采用的方法。 关闭来自 Windows 的消息,阻止进程退出编辑注册表 HKLM\Software\Microsoft\Windows\Windows 错误报告\并将 Disabled 的值设置为 true - 请参阅 msdn.microsoft.com/en-us/library/bb513638%28v=vs.85%29.aspx 【参考方案2】:

您可以创建一个与 DLL 交互的包装器应用程序,并让您的应用程序将该包装器作为一个单独的进程启动,并且只与包装器应用程序对话(例如通过 MemoryMappedFile 和名为 Mutex)。 这样,当这样的 AppCrash 发生时,您的应用程序不会受到直接影响(只有包装器被杀死) - 然后它可以自动采取您认为必要的措施(例如使对话消失和/或使用 Process.Kill 摆脱它...)。

您甚至可以将该包装器设为 Windows 服务,然后为该服务配置故障时自动重启(在 MMC/服务中)。

另一点是将操作系统设置为在这种情况下自动重启(如果这被归类为系统错误,那么您可以配置这种行为)。

编辑 - 根据评论,一些指向 MemoryMappedFile 信息的链接:

http://blogs.msdn.com/b/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx http://weblogs.asp.net/gunnarpeipman/archive/2009/06/21/net-framework-4-0-using-memory-mapped-files.aspx http://blogs.msdn.com/b/bclteam/archive/2011/06/06/memory-mapped-file-quirks.aspx http://msdn.microsoft.com/en-us/library/system.io.memorymappedfiles.memorymappedfile.aspx

【讨论】:

这是我的第一个想法,它可能会提供更好的恢复。问题是实时性质之一。该 DLL 恰好是一个非常核心的组件,大约 95% 的工作都处于一个非常紧凑的循环中,不断地调用该 DLL。将其外包给另一个应用程序并添加通信层对于我们需要它做的事情来说开销太大。如果不是因为那个障碍,这将是我最喜欢的可能解决方案。 我会试一试 - 我们有类似的东西,我真的很怀疑性能方面,但使用 .NET 4 中的 MemoryMappedFile 我们没有太大问题 - 性能非常高(尤其是.当它没有由真实文件支持时)...您甚至可以将处理逻辑中最对时间敏感的部分直接放入包装器中,并允许包装器在必要时与您的“主机”应用程序对话... 我还没有看太多 MemoryMappedFile,所以我来看看。这将是我最喜欢的方式,所以希望我可以让它发挥作用。 感谢其他链接。我将对此进行更多探索,因为我认为这是长期使用的最佳设计。不幸的是,我对这次迭代的时间限制很紧,所以我现在不得不接受上面的答案。希望我有足够的时间在它变得太远之前重新审视它。 关闭来自 Windows 的消息,该消息阻止进程退出编辑注册表 HKLM\Software\Microsoft\Windows\Windows Error Reporting\ 并将 Disabled 的值设置为 true - 请参阅 msdn.microsoft.com/en-我们/图书馆/bb513638%28v=vs.85%29.aspx【参考方案3】:

考虑以下建议: 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 和其他工具,所以它们可能会发生冲突?不知道。您是否修改过网络堆栈或网卡设备设置?

【讨论】:

以上是关于预防、避免或绕过 AppCrash的主要内容,如果未能解决你的问题,请参考以下文章

操作系统-死锁死锁发生的条件是什么?死锁的避免和预防方法

Bug预防体系

Bug预防体系——web常见产品问题及预防

如何预防计算机病毒

死锁的处理策略—预防死锁避免死锁检测和解除死锁

死锁的处理策略—预防死锁避免死锁检测和解除死锁