过滤关键/致命例外,以与AddVectoredExceptionHandler一起使用
Filtering critical/fatal exceptions for use with AddVectoredExceptionHandler
在某些情况下,在SetUnhandledExceptionFilter
(https://msdn.microsoft.com/en-us/library/library/windows/desktop/mss680634)(v = vs.85).aspx)似乎无助于捕获致命错误。情况是在关闭和不同的Abexit功能和单顿驱动器等时进行运行(清理)。同样,由于不匹配的NOExcept声明,驱灾者将终止的情况也引起了人们的关注。
使用AddVectoredExceptionHandler
(https://msdn.microsoft.com/en-us/library/windows/desktop/ms679274(v=vs.85).aspx)确实是一个很好的选择,因为它更像是一个很好的选择但是,调试者的"第一个机会例外",但是它也会被调用(方式)太多(也是普通例外,一些信号等)。
- 理想情况下,将有一种方法来判断异常是否
将被处理或结果为终止。 - 异常代码是过滤的另一种方法 - 使用CPP富有的投掷异常代码显然应该继续 - 我觉得它会太多的锅炉或试用以及获取"正确"(致命的)异常代码进行过滤的错误。
AddVectoredExceptionHandler
添加的车辆处理程序在达到基于框架的处理程序之前将处理异常。
SetUnhandledExceptionFilter
设置的过滤器将在基于帧的处理程序失败后处理异常。
正常处理(例如try...except
或try...catch
)和信号处理程序都是基于框架的操作者,信号操作者作为基于框架的最后一个基于框架的处理程序的实现。
没有可靠的方法来区分致命和非致命例外,直到链条解开为止。语言异常(代码0xE06D7363
),其他软件异常和硬件异常(例如使用代码0xC0000005
访问违规) - 所有这些都可能是致命的和非致命的。
因此,AddVectoredExceptionHandler
几乎不使用。除SetUnhandledExceptionFilter
外,您还必须处理set_terminate
,signal
,_set_invalid_parameter_handler
等。
您可以确保signal
的处理程序通过设置SIG_DFL
降回默认值,在这种情况下,它将由SetUnhandledExceptionFilter
设置为Handler。
默认的_set_invalid_parameter_handler
故意不会落到SetUnhandledExceptionFilter
设置的Handler上,但是如果将功能设置为传递给_set_invalid_parameter_handler
以提高您自己的SEH例外,它将落后于SetUnhandledExceptionFilter
设置的Handler。
我不记得set_terminate
等是什么。您需要对此进行实验。但是,作为最后的手段,您可能总是会提高自己的SEH例外,以__Except抓住它,然后传递给UnhandledExceptionFilter
,然后您的SetUnhandledExceptionFilter
回调将被调用:
__try
{
RaiseException(0xE0000001,0,0,NULL);
}
__except(UnhandledExceptionFilter(GetExceptionInformation()))
{
}
好吧,您可以做的是添加矢量化的异常处理程序,但实际上没有检查那里的异常,而是将任何一个存储在某个地方)并安装终止处理程序 - 如果被称为,那么您知道地图中的一个例外之一是错误的。为避免保留多余的数据,请在线程退出后,添加一个线程本地RAII类,该类别从地图上删除条目。当然,这是一个性能的命中(每个例外锁定地图),但是如果这确实是您想要的,那么这是一种有效的方法。
常规代码:
#include <exception>
#include <iostream>
#include <thread>
#include <Windows.h>
void termination_handler()
{
// Look at the map, you will not know which one caused it but at least have all of them
std::cout << "termination_handler calledn";
}
LONG VectoredExceptionHandler(_EXCEPTION_POINTERS *ExceptionInfo)
{
// Put exception record somewhere - e.g map of thread ids to to exception record, maybe symbols
return EXCEPTION_CONTINUE_SEARCH;
}
void foo()
{
throw std::exception();
}
int main(int argc, char** argv)
{
AddVectoredExceptionHandler(0, VectoredExceptionHandler);
std::set_terminate(termination_handler);
std::thread t(foo);
t.join();
return 0;
}
- 如何以与 API 兼容的方式重命名类成员?
- 访问类对象以与全局变量进行比较
- 如何使 printf 以与 NSLog 相同的方式打印字符缓冲区?
- 在Windows中构建GSL(GNU科学库)以与VS2015一起使用
- 如何实现自己的生成器以与 std 发行版一起使用
- 配置 Visual Studio 以与 Boost.Python 和 Python 3 配合使用
- 对象的序列化向量为STD :: String,以与MPI一起使用
- 我如何配置我的cmake文件以与Google Test和CTEST一起使用
- 如何在 conda 虚拟环境中安装 c++ 构建工具以与 cython/setproctitle 一起使用
- 是否可以重载模板函数以与 std::vector 的元素一起使用
- 过滤关键/致命例外,以与AddVectoredExceptionHandler一起使用
- 尝试实现通过引用传递的向量以与二叉树一起使用,我错过了什么
- 生成代码以与不需要重新编译的正在运行的 cpp 应用程序交互的好方法是什么?
- Visual Studio:热键/自动对.h中的函数进行排序以与.cpp保持一致的方式
- 在 Python 中以与 C++ 相同的精度乘以双倍
- 如何获取float地址以与memcpy一起使用
- 创建自定义迭代器结构以与CSTDIO一起使用
- 蓝牙可以接收数据,但不能传输数据(用C++进行套接字编程以与Matlab通信)
- 通过TCP的SIP+转换为UDP以与SIP电话通话
- 在 ubuntu 12.04 上设置 Xerces 以与 cmake 和 clang 一起使用