0

当我们的开发机器升级到 Windows 7 时,一些奇怪的事情开始发生。当我们的程序(visual c++ 2008,一些猫头鹰到 mfc 适配器,sql server 2008r2)访问例如空指针时,它不会按预期崩溃,但它会继续运行,只是关闭实际窗口。可能是个好主意,但这会使数据库事务处理成为一场噩梦。如果程序中发生隐藏崩溃,则具有未提交更改的已启动事务将保持打开状态,并且用户可以继续使用该程序。当下一个事务正常提交时,前半部分已完成事务中“挂起”的更改也会被保存。这绝对不是故意的,会导致数据损坏。

在 Windows 7 之前,我们并不关心这一点,崩溃就是崩溃。程序已关闭,所有正在运行的事务都已回滚。

我们可以做些什么来切换回旧的行为?

4

1 回答 1

1

您可以拥有自己的未处理异常例程来捕获段错误/访问冲突。

// global scope
    bool in_region_of_interest(_EXCEPTION_POINTERS *ep) {
        // TODO: Check if you aren't breaking some 3rd party functionality by exiting now.
        return ep && ep->ExceptionRecord; // Pretty much a stub.
    }
    static const bool  feelin_gentle = false; // Do we care for semi-clean exits?
    static const DWORD min_virt_rng  = 0x1000; // max virtual address that 'indicates' null ptr access.
    LONG WINAPI my_unh_exc_hndlr(_EXCEPTION_POINTERS *excPtrs)
    {
        if (in_region_of_interest(excPtrs)) {
           DWORD code = excPtrs->ExceptionRecord->ExceptionCode;
           if (EXCEPTION_ACCESS_VIOLATION == code && // If fingers burn in fire.
              min_virt_rng > excPtrs->ExceptionRecord->ExceptionInformation[1]) { // If it was a *(void*)0 that we accessed.
              if (feelin_gentle)
                 ExitProcess(code);
              else
                 TerminateProcess(GetCurrentProcess(), code);
           }
        }
        return EXCEPTION_CONTINUE_SEARCH; // Give control to the next filter.
    }

// ... somewhere in the beginning of main()
    SetUnhandledExceptionFilter(my_unh_exc_hndlr);

您不应该总是崩溃的原因是某些依赖项可能取决于能够处理段错误。您应该使用一种机制来动态地打开或关闭此功能,具体取决于您预期崩溃的位置。除非你真的确定它不会被破坏,否则最好忽略除地址为 0 或附近的无效访问之外的所有内容。如果 0x1000 从我的屁股中取出,我会取一个值,因为我不希望对象中有任何偏移量比我的程序中的大。

额外信息: http: //msdn.microsoft.com/en-us/library/windows/desktop/aa363082 (v=vs.85).aspx

于 2012-04-16T10:13:06.390 回答