在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:替换misunderstanded string * nullptr = 0xbad;
UPD2:忘掉nullptr
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;
}
答案 0 :(得分:3)
Per Remy的评论,访问冲突是Windows&#34;结构化例外,&#34;不是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!
}
答案 1 :(得分:0)
有一种误解,认为&#34;做坏事&#34;会抛出异常。 这是不正确的。如果您正在处理导致未定义行为的事情,则不应期望任何可预测的行为。如果您的平台抛出异常,那很好但是意识到您不能指望它。
最好的办法是避免编写此类代码。
有关未定义行为的更多信息,请访问Undefined, unspecified and implementation-defined behavior。
答案 2 :(得分:0)
*nullptr = 0xbad;
您导致了未定义的行为。在此之前,您甚至无法期望代码正确运行。由于编译器优化以及假定UB不会发生的权利,未定义的行为可能会在它被命中之前及时产生影响。
保护自己免于UB是没有办法的。您有来实现代码标准,阻止或消除导致它的各种错误的可能性。这是你唯一能做的就是保护自己免受UB的伤害 - 不要创造它。
这就是为什么每个团队都应该有一位语言律师能够分辨出什么是UB。 UB的影响可能非常不合适,并且在某个晚些时候或之前的某个日期在整个计划中发生。这个人应该熟悉现代的,惯用的C ++,并负责创建或至少为团队创建编码标准提供大量的咨询。
第二个要求应该是执行律师。有人可以告诉你对UB的期望。这是一种更先进的......比科学更神奇的东西。他们所知道的并不总是这样,UB活动的领域是巨大的!这些家伙不会在树上生长 - 除非是非常简约的水平,否则我没有资格。