C++ 捕获未处理的异常
在Windows中,我有一些线程。其中两个异常终止(例如,空指针解引用)。我有C++ 捕获未处理的异常,c++,winapi,exception-handling,seh,C++,Winapi,Exception Handling,Seh,在Windows中,我有一些线程。其中两个异常终止(例如,空指针解引用)。我有SetUnhandledExceptionFilter(…),它在第一个异常时开始生成转储。在第二个例外情况下,整个程序死亡。有没有办法处理这种情况?除第一个错误外,所有关键错误均应忽略 伪代码: void job() { ... RaiseException(someCode, someFlags, 0, nullptr); // or doing something wrong, like nu
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:忘记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;
}
#包括
#包含//用于异常\u访问\u冲突
#包括
#包括
长型stdcall HandleException(异常指针*exinfo)
{
静态句柄互斥=CreateMutex(nullptr,FALSE,uu TEXT(“HandleException”);
while(WaitForSingleObject(互斥,无限)!=WAIT\u OBJECT\u 0);
HANDLE event=CreateEvent(nullptr、TRUE、FALSE、_文本(“正在转储”);
卖出(“卖出”);
WaitForSingleObject(事件,5000);//执行转储例程
看跌期权(“看跌期权”);
返回异常\u执行\u处理程序;
}
整型过滤器(无符号整型代码,结构异常指针*ep)
{
放入(“过滤器中”);
返回句柄异常(ep);
}
作废职务()
{
放置(“你好”);
int*p=0x00000000;//指向NULL的指针
*p=13;//导致访问冲突异常;
}
作废安全工单(作废(*工单)()
{
__试一试{
job();
}_uu除了(过滤器(GetExceptionCode(),GetExceptionInformation()){
出口(-1);
}
}
int main()
{
SetUnhandleExceptionFilter(HandleException);
std::线程t1(std::bind(safeJob,Job));
std::线程t2(std::bind(safeJob,Job));
t1.join();
t2.连接();
返回0;
}
有一种误解,认为“做坏事”会引发异常这是不正确的。如果您所做的事情是导致未定义行为的原因,那么您不应该期望任何可预测的行为。如果您的平台抛出异常,这很好,但要意识到您不能指望它
最好避免编写这样的代码
有关未定义行为的更多信息,请访问。
*nullptr=0xbad代码>
你造成了未定义的行为。在这之前,您甚至不能期望代码正常运行。由于编译器优化和它必须假定UB不会发生的权限,未定义的行为在命中之前会及时产生影响
没有办法保护自己不受UB的伤害。您必须实现代码标准,以阻止或消除导致错误的各种错误的可能性。这是你唯一能做的保护自己免受UB伤害的事情——不要创造它
这就是为什么每个团队都应该有一个语言律师,他能说出什么是UB。UB的影响可以是非常离谱的,并且在稍后或之前的某个日期发生在整个程序中。这个人应该熟悉现代的、习惯性的C++,并负责创建,或者至少对团队的编码标准进行巨大的咨询。
第二个要求应该是执行律师。有人可以告诉你从UB期望什么。这是一种更先进的…比科学更神奇的东西。他们知道的并不总是这样,UB活动的领域是巨大的!这些家伙不是在树上生长的——我没有资格,除非是在极简主义的水平上。 < P> > ReMy的评论,访问冲突是Windows“结构化异常”,而不是C++异常,它可以用微软特定的扩展来处理,比如一个尝试语句。
例如:
__try
{
// doing something wrong
*nullptr = 0xbad;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// exception quashed!
}
听起来像是getDump
中的错误。请显示您的实际代码。nullptr
取消引用不一定会引发异常,这是未定义的行为。我不知道任何系统在取消引用nullptr
时会引发异常。它要么因segfault崩溃,要么什么也不做(尽管它可以像UB一样做任何事情)。取消引用std::nullptr_t
是一个编译错误,应该类似于*(int*)nullptr=0xbad
@Kevin:该系统称为“Windows”。winapi标记应该已经暗示了这一点。实际上,这个系统叫做英特尔x86。英特尔(和compatibles)上所谓的“segfault”是指CPU生成异常(如果我没记错的话,是GPF),Windows实际上保留了这个术语。我只听说过这些UB-gurus的传说一般来说,这是一个很好的建议,但并不真正适用于OPs案例,因为他已经知道他正在得到一个例外,并正在试图解决这个问题。更重要的是,他知道他正在获得一个“结构化异常”——这是一个WiAPI的东西,而不是C++异常。如果程序取消了一个NulLPTR,那么编程语言(C++)就不能保证应该发生什么。而另一方面,平台(Windows)则起作用。它会引发访问冲突异常。@IInspectable,但在Windows上不会显示可预测和可靠的行为。例如,Windows编译器仍可能以这种方式运行。第一个示例显示了一种情况,在这种情况下,您可能期望出现异常,但没有得到异常;第二个示例显示了一个案例,在这个案例中,您将得到一个您没有预料到的异常。(VisualStudio 2015,在发布模式下,执行前者,但没有任何规则表明Windows编译器也不能执行后者。)您可以对此答案添加解释吗?在Windows上,取消空指针引发SEH <代码>异常访问Access违规< /COR>异常,而不是C++异常。代码>\uuuuu try/\uuuuuu除外可用于处理SEH异常。有关更多详细信息,请参见MSDN。一般来说,这是一个很好的建议,但实际上并不适用于OPs案例,因为他已经知道自己遇到了异常,并正在尝试解决问题。是的,没错。由于访问零大小容器而导致的空指针解引用,而不是通过明确地这样做。编程语言(C++)不保证在程序