为啥不在应用程序崩溃时启动外部崩溃转储处理程序?

Posted

技术标签:

【中文标题】为啥不在应用程序崩溃时启动外部崩溃转储处理程序?【英文标题】:Why not launch external crash dump handler at the time the application crashes?为什么不在应用程序崩溃时启动外部崩溃转储处理程序? 【发布时间】:2015-09-10 11:11:15 【问题描述】:

我正在为我们的一个应用程序设计一个崩溃处理程序解决方案,该应用程序使用MiniDumpWriteDump() 函数创建一个崩溃转储文件。在阅读该主题时,我看到了从外部进程调用MiniDumpWriteDump() 的建议,以最大限度地提高转储文件包含正确信息的机会。常见的解决方案似乎是与应用程序进程并行运行一个看门狗进程。当应用程序崩溃时,它会以某种方式联系看门狗进程,为它提供创建崩溃转储所需的信息。然后应用程序进入睡眠状态,直到被看门狗进程终止。

我可以想象这样一个看门狗进程作为后台服务持续运行。这有很多含义,从“谁创建服务?”开始,还有“服务以哪个用户身份运行?”,以及“应用程序如何联系服务?”等等。这似乎是一个相当重量级的解决方案,我认为它不适合我的任务范围。

this SO answer 建议了一种更简单的方法:在应用程序启动时启动一个与应用程序进程紧密耦合的保护进程。这很好,但它仍然留给我以下任务: 1) 将信息保存在应用程序中的某个位置,以便在发生崩溃时如何联系保护进程; 2) 确保在应用进程正常关闭时终止守护进程。

最简单的解决方案是在崩溃发生时启动故障转储处理程序进程,将创建​​故障转储所需的所有信息作为参数传递给进程。该信息包括

崩溃的应用程序进程的进程 ID 崩溃线程的线程 ID 描述导致崩溃的异常的EXCEPTION_POINTERS 结构的地址

这种“一劳永逸”的方法之所以引人注目,是因为它不需要任何状态保留,也不需要任何复杂的超时流程管理。事实上,这种方法看起来非常简单,以至于我不禁觉得我忽略了一些东西。

反对这种方法的论据是什么?

【问题讨论】:

您应该考虑使用WER 来处理您的崩溃报告需求。我有一个应用程序使用异常过滤器作为应用程序的一部分(不在外部进程中),但是它不调用 MiniDumpWriteDump 来收集转储。异常过滤器依赖 WER 来收集转储。然后,我们将一些额外的文件添加到崩溃报告中,并在它到达时从 Microsoft WER 站点收集。 在another answer 中,Hans Passant 建议使用内存映射文件进行数据传输,而不是启动新进程。但是如果我必须实现它,我会先尝试@rrrower 的方式。让 WER 创建转储,并可能实现一个看门狗来监视新转储文件的目录。 @Thomas 我已经看到了这个答案,是的。我仍然认为“一劳永逸”的方法更简单。关于 WER:现在,收集故障转储对我们来说是全新的,我仍然需要向我的团队、我的老板、支持部门等展示这有多么有用。如果在这个阶段我要向 Microsoft 服务添加新的依赖项,我认为公司的其他人不会喜欢它。 WER 允许dumps to be collected on the local disk。那里不依赖微软。 @ThomasWeller 是的,这确实消除了对 WER 的依赖。然而,WER 提供的不仅仅是崩溃收集。有几种类型的有用报告。请记住,如果您决定自己收集崩溃报告,您还需要建立一种机制将它们运回并将它们存储在公司站点。这是 WER 为您处理的事情。 【参考方案1】:

反对“一劳永逸”方法的主要论据,正如我所说的,是在应用程序已经处于即将崩溃的状态时启动新进程是不安全的。

因此,我选择了“保护过程”方法。它带来了许多挑战,Hans Passant 拥有outlined a solution。 我还添加了一些代码in this answer,它应该有助于深度复制最重要的EXCEPTION_POINTERS 数据结构。

使用 WER,正如 cmets 中所建议的那样,看起来也是编写自己的保护过程的好选择。不过,我必须承认我还没有对此进行进一步调查。

【讨论】:

以上是关于为啥不在应用程序崩溃时启动外部崩溃转储处理程序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥应用程序在启动活动时崩溃?

Linux 中的核心转储

为啥实时多人游戏测试应用程序 ButtonClicker2000 在启动时崩溃?

程序崩溃后是否可以执行代码?

导入外部库时 Kivy 在启动时崩溃

Azure Linux Web 应用程序(节点)崩溃并显示消息:“分段错误(核心转储)”并重新启动