Vip*_*per 1 c++ stack-overflow exception seh
我SEH exceptions在StackOverflow和CodeProject.net上读过很多文章.
SEH exceptions在我的C++程序中实现处理后,我受到堆栈溢出异常的影响,我的软件没有捕获它.
经过下一部分研究后我明白,以编程方式检测这种异常是不可能的,因为我们没有可用的堆栈地址空间,因此程序内存已损坏.
我想问你有关处理堆栈溢出异常的经验.它看起来像是一个挑战,如果在非托管代码编程语言中不可能,我真的很感兴趣?
下面我将介绍我的示例程序(C++)的一部分,它可以重现stack overflow exception.它适用于任何SEH exception,但不是堆栈溢出:
LONG WINAPI SehHandler(PEXCEPTION_POINTERS pExceptionPtrs)
{
cerr << "Handled SEH exception!\n";
cerr << "ContextRecord: " << pExceptionPtrs->ContextRecord << endl;
cerr << "ExceptionRecord: " << pExceptionPtrs->ExceptionRecord << endl;
// Write minidump file
CreateMiniDump(pExceptionPtrs);
// Terminate process
TerminateProcess(GetCurrentProcess(), 1);
return EXCEPTION_EXECUTE_HANDLER;
}
int fib(unsigned int n) {
if(n == 0) return 0;
if(n == 1) return 1;
return fib(n-1)+fib(n-2);
}
int main(){
SetUnhandledExceptionFilter(SehHandler);
cout << fib(1000000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
是的,你可以从一个SO崩溃中获得一个minidump,但从来没有你现在这样做的方式.您的SehHandler()函数在触发异常的线程上运行.它处于危险状态,你有大约7080字节的紧急堆栈空间可以做你需要做的事情.如果您使用该程序,则程序将因无法访问的访问冲突异常而失败.
你不能调用MiniDumpWriteDump()并希望能够存活它,该函数需要的堆栈比你可用的多.所以这是一个没有minidump的硬kaboom.
你需要另一个线程来进行这个调用.例如,这可能是您在初始化时创建的线程,并且使用WaitForMultipleObjects()调用进行阻塞.你的SehHandler()可以调用SetEvent()来唤醒它.将PEXCEPTION_POINTERS值写入全局变量后.并无限期地阻塞以允许线程创建minidump并中止进程.
Fwiw,到目前为止,该线程的最佳位置是另一个进程.这也允许你处理完全破坏过程状态的真正令人讨厌的那些.您在初始化时开始的"保护"过程.使用命名事件来发送信号,例如,使用内存映射文件传递PEXCEPTION_POINTERS.不要在SehHandler()中启动它,进程堆不再可靠,因此CreateProcess()不能再工作了,你必须尽早完成.
| 归档时间: |
|
| 查看次数: |
1118 次 |
| 最近记录: |