StackOverflowException期间的向量异常处理

时间:2009-12-13 18:39:41

标签: c++ windows memory-management

如果我已经注册了我自己的向量异常处理程序(VEH)并且在我的进程中发生了StackOverflow异常,那么当我到达VEH时,我是否能够在堆栈上分配更多内存?分配会导致我覆盖其他一些内存吗?会发生什么事? 我知道在.Net中这就是整个堆栈在线程创建过程中提交的原因,但是假设我是用本机编写的,这种情况发生了......我能在VEH中做些什么?内存分配怎么样??

3 个答案:

答案 0 :(得分:2)

在堆栈溢出的情况下,你可以使用一小部分堆栈。这是足够的堆栈来启动一个新的线程,它将有一个全新的堆栈。从那里开始,您可以在终止之前做任何您需要做的事情。

你无法从堆栈溢出中恢复,它将涉及展开堆栈,但整个程序将在进程中被销毁。这是我为堆栈转储实用程序编写的一些代码:

// stack overflows cannot be handled, try to get output then quit   
set_current_thread(get_current_thread());
boost::thread t(stack_fail_thread);

t.join(); // will never exit

所有这一切都得到了线程的句柄,因此堆栈转储机制知道要转储哪个线程,启动一个新线程来执行转储/日志记录,并等待它完成(这不会发生,线程调用{ {1}})。

为完整起见,exit()看起来像这样:

get_current_thread()

所有这些都是“简单”的功能,不需要很大的工作空间(请记住,编译器可能会内联这些msot,删除函数调用)。相反,你不能抛出异常。这不仅需要更多的工作,而且析构函数可以做很多工作(比如解除分配内存),这也很复杂。

您最好的办法是开始一个新的主题,尽可能多地保存有关您的申请的信息,然后终止。

答案 1 :(得分:1)

No, you can't allocate memory in vectored exception handler.

MSDN says it explicitly:

"The handler should not call functions that acquire synchronization objects or allocate memory, because this can cause problems. Typically, the handler will simply access the exception record and return."

答案 2 :(得分:0)

堆栈需要是连续的,因此您不能只分配任何随机内存,而必须分配地址空间的下一部分。

如果您愿意预先分配地址空间(即只保留一系列地址而不实际分配内存),则可以使用VirtualAlloc。首先,使用MEM_RESERVE标志调用它以留出地址空间。稍后,在异常处理程序中,您可以使用MEM_COMMIT再次调用它,以将物理内存分配给预先保留的地址空间。