背景

  • 我有一个应用程序 噗-崩溃[1].我相当肯定,这是由于一个吹堆。
  • 该应用程序是多线程的。
  • 我编写有"Enable C++ Exceptions: Yes With SEH Exceptions (/EHa)".
  • 我已经写了一个SE翻译职能,并呼 _set_se_translator() 与。
  • 我有书面的功能和安装 set_terminate()set_unexpected().
  • 获得堆叠溢出时,我必须运行中释放的模式,负载过重,对几天。下运行的一个调试器不是一个选项,因为该申请不能进行足够快的速度实现运行时必要的,看看这一问题。
  • 我可以模拟问题通过增加无限的递归在执行的功能之一,因此考试的捕的 EXCEPTION_STACK_OVERFLOW 例外。
  • 我WinDBG设置的崩溃转储程序,并获得良好的信息对于所有其他会崩溃的问题,但是 不是这一个.崩溃转储将只包含一个线程,这是'Sleep()'ing.所有其他线已经退出。

这个问题

没有任何东西,我已经试过了捡的 EXCEPTION_STACK_OVERFLOW 例外。

任何人都不会知道如何保证获得一个机会,在这个异常运行期间在释放模式?

定义

  1. 噗-崩溃:该应用程序的崩溃会"噗"消失的无影无踪。

(考虑到这个名字的站点,我有点惊奇这个问题不在这里了!)

注意到

  1. 一个答案是公布有关简要调整堆尺寸的潜在力问题越早,并允许捕捉它有一个调试器。这是一个聪明的思想,但不幸的是,我不认为这会有所帮助。问题是有可能引起的一个角落的情况下导致无限递归。缩短该堆不会暴露问题的任何更早和可能会导致一个不相关的崩溃已经有效深码。不错的主意,不过,并感谢张贴,即使你有没有去除它。
有帮助吗?

解决方案

一切现有windows xp会不能(或者是困难的)通常能够捕堆溢出。随着xp,可以设置 量异常的处理程序 这一得到机会在堆溢出之前的任何基于栈(结构异常)处理程序(这是正常的原因-结构异常的处理程序栈-based)。

但有真的没有多少你可以做到,甚至如果你能到陷阱这样的一个例外。

他的博客,cbrumme(对不起,没有他/她的真名)讨论了一堆页邻近的保护页(一个,那产生的堆溢出),可能会被用于搁置.如果你可以挤压你的恢复代码使用的只是一堆页-你可以免费尽你的逻辑允许。否则,应用程序是很多死在遇到堆溢出。只有其他合理的事情要做,具有困,是编写一个垃圾场文件后面的调试。

希望这有所帮助。

其他提示

我不相信你是在正确的轨道,在诊断这一堆溢出。

但在任何情况下,事实上,你得到了 噗!, 加上你看到的在WinDbg

崩溃转储将只包含一个线程,这是'Sleep()'ing.所有其他线已经退出。

建议对我来说,有人呼吁C RTL exit()function,或可能被称为Windows API TerminateProcess()直接。可能有些事要做你中断的处理程序或没有。也许事情在例外处理逻辑,具有重新入口检查和任意决定退出()如果重新进入.

我的建议是来修补你的可执行文件的投入也许INT3调试在入境点到出口(的),如果它是静态相联系,或如果这是动态的联系,修补的进口,也修补的任何进口kernel32::TerminateProcess扔DebugBreak()instead.

当然,exit()和/或TerminateProcess()可以被称为一个正常关闭,太,所以你必须筛选出虚假的警报,但是如果你可以得到的话叠的情况下,它只是要证明,你应该有什么你需要的。

编辑添加:只是简单地写入自己版本的出口(的)和联它在相反的CTRL版本可能做到。

我记得码从以前的工作场所,听起来类似的具有明确的边界检查堆的指针和投掷的一个例外。

它已经有一段时间,因为我已经摸C++不过,即使我没有碰它,我不知道我在做什么,所以警告实现有关可携带性/可靠性所述的建议。

你有没有考虑 ADPlus 从调试工具,用于Windows?

ADPlus重视国家开发银行的调试进程中的"崩溃"的模式,并将生成垃圾场崩溃对于大多数例外情况的过程产生。基本上,你就跑"ADPlus-崩溃的-p yourPIDhere",它执行一个侵入性的重视,并开始记录。

给你上面的评论关于下运行的一个调试器,我只想补充一点,加勒比开发银行增加了几乎为零开销在崩溃的模式在一个体面的(双核心,2GB RAM)机器,所以不要让你抱回来尝试。

你可以产生的调试的符号没有禁用的优化。事实上,你应该做的,反正。它只是使调试困难。

和文件 _set_se_translator 说每个线都有其自己本身的翻译。你设置一个为每个线?

set_unexpected 可能是一个没有作,至少根据本VS2005年的文件。每个线程也有其自己的 terminate 处理程序,所以你应该安装的,每线。

我也强烈建议 使用本身的翻译。它需要 硬件 例外情况,你不应该忽略(即,你真的应该记录的错误和终止),并把它们变成什么你可以忽略(C++例外情况)。如果你想抓住这种错误,使用 __try/__except 处理程序。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top