我如何保证在C+;中捕获异常堆栈溢出结构化异常+;在VisualStudio2005下? 背景 我有一个应用程序出现了Poof崩溃[1]。我相当肯定这是因为烟囱被吹坏了 该应用程序是多线程的 我编译的是“启用C++异常:是的,有SEH异常(/ EHa)< /代码>”。 我编写了一个SE Translator函数,并用它调用了\u set\u SE\u Translator() 我已经为和setupset\u terminate()和set\u unexpected()编写了函数 为了获得堆栈溢出,我必须在重载下以释放模式运行几天。在调试器下运行不是一个选项,因为应用程序的执行速度不够快,无法实现查看问题所需的运行时 我可以通过在执行其中一个函数时添加无限递归来模拟这个问题,从而测试捕获EXCEPTION\u STACK\u OVERFLOWEXCEPTION 我已将WinDBG设置为崩溃转储程序,并获得了有关所有其他崩溃问题的良好信息,但不是此问题。崩溃转储将只包含一个线程,即“Sleep()”。所有其他线程都已退出 问题

我如何保证在C+;中捕获异常堆栈溢出结构化异常+;在VisualStudio2005下? 背景 我有一个应用程序出现了Poof崩溃[1]。我相当肯定这是因为烟囱被吹坏了 该应用程序是多线程的 我编译的是“启用C++异常:是的,有SEH异常(/ EHa)< /代码>”。 我编写了一个SE Translator函数,并用它调用了\u set\u SE\u Translator() 我已经为和setupset\u terminate()和set\u unexpected()编写了函数 为了获得堆栈溢出,我必须在重载下以释放模式运行几天。在调试器下运行不是一个选项,因为应用程序的执行速度不够快,无法实现查看问题所需的运行时 我可以通过在执行其中一个函数时添加无限递归来模拟这个问题,从而测试捕获EXCEPTION\u STACK\u OVERFLOWEXCEPTION 我已将WinDBG设置为崩溃转储程序,并获得了有关所有其他崩溃问题的良好信息,但不是此问题。崩溃转储将只包含一个线程,即“Sleep()”。所有其他线程都已退出 问题,c++,debugging,exception-handling,stack-overflow,structured-exception,C++,Debugging,Exception Handling,Stack Overflow,Structured Exception,我尝试过的任何事情都没有导致出现EXCEPTION\u STACK\u OVERFLOW异常 有人知道如何保证在发布模式下运行时有机会出现此异常吗 定义 Poof崩溃:应用程序因“Poof”而崩溃,并消失得无影无踪 (考虑到这个网站的名称,我有点惊讶这个问题还没有出现在这里!) 笔记 一个简短的回答是关于调整堆栈大小以可能更快地强制解决问题,并允许使用调试器捕获它。这是一个聪明的想法,但不幸的是,我不相信它会有帮助。这个问题很可能是由导致无限递归的一个角落情况引起的。缩短堆栈不会很快暴露问题,并

我尝试过的任何事情都没有导致出现
EXCEPTION\u STACK\u OVERFLOW
异常

有人知道如何保证在发布模式下运行时有机会出现此异常吗

定义
  • Poof崩溃:应用程序因“Poof”而崩溃,并消失得无影无踪
  • (考虑到这个网站的名称,我有点惊讶这个问题还没有出现在这里!)

    笔记
  • 一个简短的回答是关于调整堆栈大小以可能更快地强制解决问题,并允许使用调试器捕获它。这是一个聪明的想法,但不幸的是,我不相信它会有帮助。这个问题很可能是由导致无限递归的一个角落情况引起的。缩短堆栈不会很快暴露问题,并且可能会在有效深度的代码中导致不相关的崩溃。好主意,谢谢你把它贴出来,即使你把它删除了

  • 我记得以前一个工作场所的代码听起来很相似,它对堆栈指针进行显式边界检查,并手动抛出异常


    虽然我已经接触过C++,但是我触摸它的时候,我不知道我在做什么,所以警告了实现的可信性和可靠性。

    < P>可以在不禁用优化的情况下生成调试符号。事实上,你无论如何都应该这样做。这只会使调试更加困难

    \u set\u se\u translator
    的文档说明每个线程都有自己的se translator。您是否为每个线程设置一个

    set\u unexpected
    至少根据VS 2005文档,可能是不可操作的。每个线程也有自己的
    terminate
    处理程序,因此您也应该为每个线程安装该处理程序

    我还强烈建议不要使用SE翻译。它需要硬件您不应该忽略的异常(即,您应该真正记录错误并终止),并将它们转化为您可以忽略的东西(C++异常)。如果要捕获此类错误,请使用除处理程序之外的
    \uu try/\uu处理程序。

    您是否考虑过Windows调试工具


    ADPlus以“崩溃”模式将CDB调试器连接到进程,并将为该进程生成的大多数异常生成崩溃转储。基本上,您运行“ADPlus-crash-pyourpidhere”,它执行入侵连接并开始记录


    鉴于您在上面关于在调试器下运行的评论,我只想补充一点,CDB在一台像样的(双核、2GB RAM)机器上的崩溃模式下几乎不会增加任何开销,所以不要因此而放弃尝试。windows xp之前的所有东西通常都无法(或更难)捕获堆栈溢出。随着xp的出现,您可以设置在任何基于堆栈的(结构化异常)处理程序之前获得堆栈溢出的机会(这正是结构化异常处理程序基于堆栈的原因)。 但即使你能捕捉到这样一个异常,你也真的无能为力。 在中,cbrumme(抱歉,没有他/她的真名)讨论了与保护页(生成堆栈溢出的那一页)相邻的堆栈页,该页可能用于回退。如果您可以压缩回退代码以仅使用一个堆栈页,那么您可以在逻辑允许的范围内释放尽可能多的代码。否则,当遇到堆栈溢出时,应用程序将几乎死机。唯一其他合理的方法是编写一个转储文件,以便以后调试


    希望有帮助。

    我不相信您将此诊断为堆栈溢出是正确的

    但无论如何,事实上,你得到了一个便便!,加上你在WinDbg中看到的

    崩溃转储将只包含一个线程,即“Sleep()”。所有其他线程都已退出

    我认为有人调用了C RTL exit()函数,或者可能直接调用了Windows API TerminateProcess()。这可能与中断处理程序有关,也可能与否。可能异常处理逻辑中的某些东西有一个重新进入检查,如果它被重新进入,它会任意决定退出()

    我的建议是修补您的可执行文件,以便在退出()的入口点放置一个INT 3调试,如果它是静态链接的,或者是动态链接的,则修补导入,并修补kernel32::TerminateProcess的任何导入,以抛出DebugBreak()

    当然,正常关机时也可能会调用exit()和/或TerminateProcess(),因此您必须过滤掉错误警报,但如果您能够获得调用堆栈,则它只是