竞天问 2021-08-31 16:05 采纳率: 0%
浏览 182
已结题

C++的异常不能触发我设置的UnhandledExceptionFilter

Win10,VS2019
代码如下:

LONG __stdcall DummyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
{
    printf("DummyUnhandledExceptionFilter called\n");
    return EXCEPTION_CONTINUE_SEARCH;
}


int wmain(const int argc, const wchar_t* argv[])
{
    SetUnhandledExceptionFilter(DummyUnhandledExceptionFilter);

    std::thread crash(
        []()
        {

            Sleep(1 * 1000);
            auto pOld = SetUnhandledExceptionFilter(NULL);
            if (pOld != &DummyUnhandledExceptionFilter)
            {
                printf("unequal\n");
            }
            SetUnhandledExceptionFilter(pOld);
#if 0
            RaiseException(0, 0, 0, 0);    //可以触发
#elif 1
            throw std::exception();    //不能触发
#else
            int* p = 0;
            p[0] = 1;    //可以触发
#endif
        }
    );

    crash.join();
}

在非主线程里,这三种触发异常的代码的行为不一样,RaiseException和空指针的访问违规是可以调用到DummyUnhandledExceptionFilter的,但是C++ 的throw并不能。(如果是在主线程throw,是可以调用到DummyUnhandledExceptionFilter)
在《Windows核心编程》第五版25.5节(683页)里说:

“我们应该了解Microsoft的Visual C++编译器使用操作系统的结构化异常机制来实现C++异常处理机制。……编译器也会为C++ throw语句生成对Window RaiseException函数的调用……”
按这个说法,前两种触发异常的方式的效果应该是一样的,但是现在效果确实不一样。而且我在汇编里跟踪,throw时也确实调用了RaiseException,是通过_CxxThrowException函数来进行的,但是最终效果应该一样吧,但是为什么throw就是不能调用到DummyUnhandledExceptionFilter呢?
我在写这个问题的时候查到了std::set_terminate函数,但是这个函数也调用不到设置的terminate_handler。在Debug模式下倒是可以。


请问哪位可以帮我理清这些东西的行为吗?或者给个链接、书的章节等,都可以,谢谢!

  • 写回答

1条回答 默认 最新

  • 竞天问 2021-09-01 15:05
    关注

    同样的代码,在std::thread里执行是这样的行为,但是使用_beginthread开启另外一个线程就可以正确触发,为什么呢?std::thread还会对异常做什么特别处理吗?

    评论

报告相同问题?

问题事件

  • 系统已结题 9月8日
  • 修改了问题 8月31日
  • 修改了问题 8月31日
  • 创建了问题 8月31日

悬赏问题

  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题