是否有任何方法可以防止应用程序在堆损坏时崩溃? - C编程语言

时间:2010-09-29 18:18:50

标签: c memory free heap

有时在执行中我在尝试释放内存时会在VS2010中收到此错误消息:

  

Windows在[APPNAME] .exe。

中触发了断点      

这可能是由于堆的损坏,这表示[APPNAME] .exe或它已加载的任何DLL中的错误。

     

这也可能是由于用户在[APPNAME] .exe具有焦点时按下F12。

     

输出窗口可能包含更多诊断信息。

这意味着堆或指针有问题。

我的问题是,当我的应用程序构建为发行版时,此错误会崩溃。

此外,这只是一个更大应用程序的模块,当崩溃的时候会崩溃。

我希望能够处理此错误。

来自msdn的“免费”:

  

如果在释放内存时发生错误,则会根据操作系统中有关故障性质的信息设置errno。有关更多信息,请参阅errno,_doserrno,_sys_errlist和_sys_nerr。

errno_t _get_errno( int * pValue );函数返回错误代码。

如果我按上面显示的错误消息继续,此函数将返回错误代码。 使用此代码,我可以检测错误,创建调用堆栈并轻轻退出我的函数。

是否有任何编译器开关或某些东西阻止应用程序在空闲失败时崩溃并允许我以我的方式退出?

4 个答案:

答案 0 :(得分:8)

如果堆已损坏,则所有投注均已关闭。内存分配可能会失败(除非它们在堆栈中),它们可能会返回指向古怪区域的指针,甚至是堆上的现有内容可能会受到严重损害。在这种情况下,你实际上最好不要崩溃,因为你采取的任何行动(甚至试图优雅地退出)可能会让事情变得更糟。

找到在堆上修改内容的代码,然后修复或删除它。

答案 1 :(得分:4)

理论上,您尝试阻止您的应用使用SEH崩溃。 AFAIK“调试断点”是一种可以处理的SEH异常。

__try {
    // do something here
} __except(EXCEPTION_EXECUTE_HANDLER) {
}

上面的__try / __except块将捕获所有异常(包括C ++和SEH)。

<强>无论其

我相信你不应该这样做。堆损坏,以及任何其他无效的内存访问 - 是错误一旦发生这种情况 - 损害通常是无法恢复。您可以防止崩溃(希望如此),但您不能保证您的程序能够执行它应该执行的操作。从现在开始,它可能会在任何其他地方崩溃。

我建议您查找,而不是防止崩溃,而是敢于覆盖禁用内存并破坏堆的歹徒。

答案 2 :(得分:4)

修复代码,而不是试图忽略这么严重的错误。您的生产代码中不应该有如此严重的内存错误。 AFAIK没有简单的方法来解决这个问题,这是有充分理由的。

顺便说一下,我以为对话框只出现在调试模式下。在发布模式下,不应检测到内存错误,应用程序应立即崩溃(或运行损坏的堆,yuk)。

答案 3 :(得分:0)

许多Windows程序使用HeapSetInformationHeapEnableTerminationOnCorruption来确保在检测到堆损坏时程序立即崩溃。这是一种安全措施,因为堆损坏可能是可利用的。在堆损坏时立即崩溃是唯一理智的事情。

但是如果您正在尝试调试,并且它是发布版本,则此设置可能会使调试问题变得困难。听起来你有一个模块在别人的应用程序中运行(虽然我不能从你的描述中确定)。在这种情况下,可能是另一个应用程序正在设置堆终止标志。不幸的是,一旦设置(每个过程)就不能取消设置。

发生崩溃时,您需要附加调试器以生成转储文件,并尝试从中进行调试。