为什么SetUnhandledExceptionFilter不能捕获一些exception,但AddVectoredExceptionHandler可以做到

我遇到了一个问题,即传递给SetUnhandledExceptionFilter的函数在exception代码c0000374提升时没有被调用。 但它可以正常工作,例外代码为c0000005。 然后,我尝试使用AddVectoredExceptionHandler ,而没有问题,处理函数被调用正确。

这是API错误? 我可以在任何地方使用AddVectoredExceptionHandler而不是SetUnhandledExceptionFilter吗?

这两个函数正常工作

// Exception code c0000005 int* p1 = NULL; *p1 = 99; 

只有AddVectoredExceptionHandler可以捕获这个exception。 (为了certificate它不依赖于运行时库,我手动引发exception,结果相同。)

 // Exception code c0000374 RaiseException(0xc0000374, 0, 0, NULL); 

testing程序。

 #include <tchar.h> #include <fstream> #include <Windows.h> LONG WINAPI VectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { std::ofstream f; f.open("VectoredExceptionHandler.txt", std::ios::out | std::ios::trunc); f << std::hex << pExceptionInfo->ExceptionRecord->ExceptionCode << std::endl; f.close(); return EXCEPTION_CONTINUE_SEARCH; } LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { std::ofstream f; f.open("TopLevelExceptionHandler.txt", std::ios::out | std::ios::trunc); f << std::hex << pExceptionInfo->ExceptionRecord->ExceptionCode << std::endl; f.close(); return EXCEPTION_CONTINUE_SEARCH; } int _tmain(int argc, _TCHAR* argv[]) { AddVectoredExceptionHandler(1, VectoredExceptionHandler); SetUnhandledExceptionFilter(TopLevelExceptionHandler); // Exception code c0000374 RaiseException(0xc0000374, 0, 0, NULL); // Exception code c0000005 // int* p1 = NULL; // *p1 = 99; return 0; } 

它发生在MSVC CRT启动这个代码:

  /* * Enable app termination when heap corruption is detected on * Windows Vista and above. This is a no-op on down-level OS's * and enabled by default for 64-bit processes. */ if (!_NoHeapEnableTerminationOnCorruption) { HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); } 

如果你想禁用它( 推荐),把nohetoc.obj链接到你的程序。

实际上,在检测到堆损坏后,实际上直接在源代码中RtlReportCriticalFailure ,在堆管理器中调用RtlReportCriticalFailure 在这个函数中注册的SEH处理程序调用RtlReportException ,紧接着是NtTerminateProcess

我只能得出这样的结论:SEH处理程序是故意避免的 – 堆被破坏,堆栈内容(因此SEH注册)也被怀疑; 无论如何,应用程序无法从堆损坏中合理地恢复。