如果您在进程崩溃后在进程中分配内存会发生啥?

Posted

技术标签:

【中文标题】如果您在进程崩溃后在进程中分配内存会发生啥?【英文标题】:What happens if you allocate memory in a process once it has crashed?如果您在进程崩溃后在进程中分配内存会发生什么? 【发布时间】:2013-12-25 13:28:00 【问题描述】:

我一直在与Google breakpad 合作进行崩溃报告。它强调的一件事是,一旦进程崩溃,就不应该分配内存。它说一旦进程崩溃,在进程中分配内存是不“安全的”。

这里的“安全”到底是什么意思?

【问题讨论】:

如何让程序执行,然后在收到SIGABRT后分配内存? 有可能!您可以为 SIGABRT 和 SIGSEGV 设置处理程序并在那里分配内存。我使用该方法在 QT 应用程序中显示带有堆栈跟踪的 BSOD。在调用new QWidget 并显示必要的信息后,我只需使用 `sleep(1)' 结束崩溃的线程进入无限循环。 @loentar 当然不是说你不能分配内存。据我所知,微软的 minidump 进程分配内存。但是这个崩溃报告引擎明确警告不要这样做。 【参考方案1】:

这是不安全的,因为标准库可能处于损坏状态,当您需要更多内存时会导致第二次崩溃。

如果你想打印一些东西,不要分配内存(例如使用局部变量)

【讨论】:

这是这里唯一正确的答案。崩溃处理程序将是 SIGSEGV 信号处理程序。堆栈使用没问题,因为它会占用自己的堆栈帧,但堆可能处于不正确的状态,因此内存分配可能会触发第二次崩溃。 我们读的是同一个问题吗? “它说一旦进程崩溃就在进程中分配内存是不'安全'的。'安全'在这里到底是什么意思?” (虽然你的回答也非常正确。我第一次阅读时一定错过了。)【参考方案2】:

一旦进程崩溃,您最好的希望就是在永久退出进程之前了解发生了什么。因此,“安全”被简化为您的错误报告代码,不会在原始崩溃之上导致其自身的崩溃。这就是为什么此时您的选择有限:例如,尝试分配内存是危险的,因为最初的崩溃可能是由损坏的堆引起的。

【讨论】:

【参考方案3】:

你真的不应该在崩溃后做任何过于复杂的事情,以免你挂起或在你的崩溃代码中崩溃。两个主要原因是:锁和全局变量。如果您的进程在持有锁时崩溃,并且您在崩溃后所做的任何事情都需要该锁,那么它要么会出错,要么会挂起。还有很多状态信息存储在全局变量中。不仅是程序中声明的内容,还有库甚至动态链接器/加载器使用的许多东西。如果其中任何一个是坏的,调用使用这些全局变量之一的函数的结果是不可预测的。

【讨论】:

以上是关于如果您在进程崩溃后在进程中分配内存会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中分配内存时发出 SIGKILL

在 32 位 .NET 进程中分配超过 1,000 MB 的内存

AppDomain 地址空间

当您在 Linux 中更改进程所有权 (uid/gid) 时,已打开的文件会发生啥情况?

c#:内存中的变量会发生啥?

内存分配与回收策略