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

Posted

技术标签:

【中文标题】程序崩溃后是不是可以执行代码?【英文标题】:Is it possible to execute code after a program has crashed?程序崩溃后是否可以执行代码? 【发布时间】:2019-02-22 16:39:53 【问题描述】:

我希望能够在发生崩溃时从应用程序中转储信息。是否可以执行诸如在程序崩溃时分配要调用的回调之类的操作?回调将从应用程序中转储数据。转储的数据将是特定于应用程序的,可能位于堆栈转储中,但格式更易于非程序员阅读。

操作系统是 Windows 10。

【问题讨论】:

我认为这是你应该从你的操作系统而不是你的程序中问的问题。 “我希望能够在发生崩溃时从应用程序中转储信息” 这通常已经由操作系统完成(查找 堆栈跟踪转储) 有一些工具可以做到这一点。所以肯定是可以的,但是多少取决于你的操作系统 您的目标操作系统是什么? Windows 有 SEH,但不确定 Linux。 崩溃的概念是存在于语言范围之外的东西。除非您特别询问如何处理 std::abortstd::terminate 或其他语言指定的进程结束函数。但是,如果您询问处理意外崩溃的问题,那么这是您必须在 c++ 范围之外解决的问题。这完全取决于您运行代码的方式和内容。 【参考方案1】:

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

通常,根据操作系统,进程将在终止之前从操作系统接收信号。信号处理程序(如果已注册且未屏蔽信号)有机会在进程终止之前执行代码。

终止后,进程不存在,无法执行代码,内存也无法访问。

可以在信号处理程序中安全使用的函数是有限的。 C++ 标准保证了以下函数的安全性(如果我遗漏了一些函数,可能并不详尽):

_Exit
abort
forward
initializer_list functions
memcpy
memmove
move
move_if_noexcept
numeric_limits members
quick_exit
signal
type traits
plain lock-free atomic operations

请注意,标准所保证的功能都不能输出。您的操作系统也可能允许其他功能,并且应该有列出它们的文档。 POSIX 标准保证openwrite 函数的安全性,可用于输出。


以上假设崩溃的根源在程序之外(例如,用户请求操作系统终止,或者您的进程访问无效内存并且操作系统对此作出反应)。如果崩溃的源头来自程序内部,特别是如果std::terminate被你或标准库调用,那么你可以注册一个std::terminate_handler,它不像信号处理程序那样受限。

【讨论】:

【参考方案2】:

Windows 程序的一种可能解决方案是使用 MiniDumpWriteDump 函数。本页描述了在 Windows 中发生崩溃时编写小型转储的不同替代方案 - https://docs.microsoft.com/en-us/windows/desktop/dxtecharts/crash-dump-analysis

【讨论】:

仅链接的答案在这里并不是很好(链接可能会过期并出现 404)。至少引用文档在那里所说的内容。

以上是关于程序崩溃后是不是可以执行代码?的主要内容,如果未能解决你的问题,请参考以下文章

仅在发布配置中第二次执行后应用程序才会崩溃

执行 exec 命令后 Android 应用程序崩溃

恢复执行后被调试的程序崩溃

在应用程序崩溃时执行代码

执行后台获取完成处理程序后应用程序崩溃

当程序崩溃发生后,我做了如下工作