捕获未经处理的异常
Catching unhandled exceptions
在Windows中,我有一些线程。其中两个异常终止(例如,空指针取消引用)。我有SetUnhandledExceptionFilter(...)
在第一个异常时开始生成转储。在第二个例外情况下,整个程序死亡。有没有办法处理这种情况?除第一个错误外,所有严重错误都应忽略。
伪代码:
void job()
{
...
RaiseException(someCode, someFlags, 0, nullptr); // or doing something wrong, like nullptr dereference
}
int main() {
SetUnhandledExceptionFilter(getDump);
std::thread t1(job), t2(job);
...
}
UPD:替换误解的字符串 *nullptr = 0xbad;
UPD2:忘记空点
UPD3:到目前为止,我找到了这个解决方法
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
#include <mutex>
LONG __stdcall HandleException(EXCEPTION_POINTERS* exinfo)
{
static HANDLE mutex = CreateMutex(nullptr, FALSE, __TEXT("HandleException"));
while(WaitForSingleObject(mutex, INFINITE) != WAIT_OBJECT_0);
HANDLE event = CreateEvent(nullptr, TRUE, FALSE, __TEXT("Doing Dump"));
puts("Doing Dump");
WaitForSingleObject(event, 5000); // do dump routine
puts("Done Dump");
return EXCEPTION_EXECUTE_HANDLER;
}
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
{
puts("in filter.");
return HandleException(ep);
}
void Job()
{
puts("hello");
int *p = 0x00000000; // pointer to NULL
*p = 13; // causes an access violation exception;
}
void safeJob(void (*job)())
{
__try {
job();
} __except (filter(GetExceptionCode(), GetExceptionInformation())) {
exit(-1);
}
}
int main()
{
SetUnhandledExceptionFilter(HandleException);
std::thread t1(std::bind(safeJob, Job));
std::thread t2(std::bind(safeJob, Job));
t1.join();
t2.join();
return 0;
}
根据 Remy 的评论,访问冲突是 Windows"结构化异常",而不是C++异常,可以使用特定于Microsoft的扩展(如 try-except 语句)进行处理。
https://msdn.microsoft.com/en-us/library/s58ftw19.aspx
例:
__try
{
// doing something wrong
*nullptr = 0xbad;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// exception quashed!
}
有一种误解,认为"做坏事"会引发异常。这是不正确的。如果您正在做的事情是导致未定义行为的原因,则不应期望任何可预测的行为。如果您的平台抛出异常,那很好,但要意识到您不能指望它。
最好的办法是避免编写此类代码。
有关未定义行为的更多信息,请参阅未定义、未指定和实现定义的行为。
*nullptr = 0xbad;
您导致了未定义的行为。 在它正确运行之前,您甚至不能期望该代码。 由于编译器优化以及它必须假定 UB 不会发生的权利,未定义的行为可能会在命中之前及时产生影响。
没有办法保护自己免受UB的侵害。您必须实现代码标准,以阻止或消除导致错误的类型的可能性。 这是您唯一能做的保护自己免受UB侵害的事情 - 不要创建它。
这就是为什么每个团队都应该有一个语言律师,他可以分辨什么是UB。 UB的效果可能非常不合时宜,并且在以后或以前的某个日期在整个程序中都很明显。 这个人应该熟悉现代的惯用C++,并负责创建,或者至少发挥巨大的建议,以创建编码标准的团队。
第二个要求应该是执行律师。 可以告诉您对UB的期望的人。 这是一个更高级的...比科学更神奇的东西。 他们所知道的并不总是这样,UB活动的领域是巨大的! 这些家伙不长在树上——除了在非常简约的水平上,我没有资格。
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- 使用 stoi 功能进行异常处理
- 子系统中的异常处理:本机
- 与异常处理程序中的操作员<<不匹配
- 数组 C++ 上的异常处理程序
- 异常处理:如果用户输入不是三个特定字符之一
- C++ 异常处理错误输出
- 视觉 std::矢量无异常:警告 C4530:使用了C++异常处理程序,但未启用展开语义.指定 /EHsc
- C++交换机状态异常处理
- 在字符串类上的成员函数和out_of_range异常处理
- 奇怪的消息 (_Base_bitset::_M_do_to_ulong) 从溢出异常处理程序中打印出来
- 执行视觉工作室异常处理模式
- 为什么隐式转换在异常处理中从派生到基?
- C++执行期间的类成员函数错误/异常处理
- C++ 中未处理的异常处理程序
- 用户定义的异常处理
- C :ScopeGuard vs返回支票和异常处理
- 异常处理期间的类型解析