标签: structured-exception

我应该在C++中了解结构化异常(SEH)?

每个C++开发人员都应该知道哪些关于结构化异常的重要观点?

c++ exception-handling exception seh structured-exception

42
推荐指数
4
解决办法
3万
查看次数

为什么64位Windows无法解除用户内核用户异常?

为什么64位Windows在异常期间不能展开堆栈,如果堆栈跨越内核边界 - 当32位Windows可以?

整个问题的背景来自:

消失的OnLoad异常 - x64中的用户模式回调异常的情况

背景

在32位Windows中,如果我在我的用户模式代码中抛出异常,那是从内核模式代码调用的,这是从我的用户模式代码调用的,例如:

User mode                     Kernel Mode
------------------            -------------------
CreateWindow(...);   ------>  NtCreateWindow(...)
                                   |
WindowProc   <---------------------+                                   
Run Code Online (Sandbox Code Playgroud)

Windows中的结构化异常处理(SEH)可以展开堆栈,通过内核模式展开回到我的用户代码,在那里我可以处理异常,并且我看到有效的堆栈跟踪.

但不是在64位Windows中

64位版本的Windows无法执行此操作:

由于复杂的原因,我们无法在64位操作系统(amd64和IA64)上传播异常.自从Server 2003的第一个64位版本发布以来,情况一直如此.在x86上,情况并非如此 - 异常通过内核边界传播,并最终将帧移回

由于在这种情况下无法回溯可靠的堆栈跟踪,因此必须做出决定:让您看到非荒谬的异常,或者完全隐藏它:

当时的内核架构师决定采用保守的AppCompat友好方法 - 隐藏异常,并希望最好.

本文接着讨论了所有64位Windows操作系统的表现如何:

  • Windows XP 64位
  • Windows Server 2003 64位
  • Windows Vista 64位
  • Windows Server 2008 64位

但是从Windows 7(和Windows Server 2008)开始,架构师改变了主意 - 有点像.对于 64位应用程序(不是32位应用程序),它们(默认情况下)会停止抑制这些用户内核用户异常.所以,默认情况下,在:

  • Windows 7 64位
  • Windows Server 2008

所有64位应用程序都会看到这些异常,他们从来没有看到它们.

在Windows 7中,当本机x64应用程序以这种方式崩溃时,将通知 …

windows 64-bit structured-exception windows64 windows-appcompat-platform

37
推荐指数
2
解决办法
4410
查看次数

__finally应该在EXCEPTION_CONTINUE_SEARCH之后运行吗?

在下面的代码中,函数以foo递归方式调用一次.内部调用导致引发访问冲突.外部调用捕获异常.

#include <windows.h>
#include <stdio.h>

void foo(int cont)
{
    __try
    {
        __try
        {
            __try
            {
                if (!cont)
                    *(int *)0 = 0;
                foo(cont - 1);
            }
            __finally
            {
                printf("inner finally %d\n", cont);
            }
        }
        __except (!cont? EXCEPTION_CONTINUE_SEARCH: EXCEPTION_EXECUTE_HANDLER)
        {
            printf("except %d\n", cont);
        }
    }
    __finally
    {
        printf("outer finally %d\n", cont);
    }
}

int main()
{
    __try
    {
        foo(1);
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        printf("main\n");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里的预期输出应该是

inner finally 0
outer finally 0
inner finally 1
except 1 …
Run Code Online (Sandbox Code Playgroud)

c++ winapi seh structured-exception

7
推荐指数
1
解决办法
237
查看次数

如何保证在Visual Studio 2005下在C++中捕获EXCEPTION_STACK_OVERFLOW结构化异常?

背景

  • 我有一个Poof-Crash的应用程序[ 1 ].我很确定这是因为堆栈爆炸.
  • 该应用程序是多线程的.
  • 我正在编译" Enable C++ Exceptions: Yes With SEH Exceptions (/EHa)".
  • 我写了一个SE翻译功能并_set_se_translator()用它调用.
  • 我已经写了功能和设置set_terminate()set_unexpected().
  • 为了获得Stack Overflow,我必须在高负载下以释放模式运行几天.在调试器下运行不是一个选项,因为应用程序执行速度不足以达到查看问题所需的运行时间.
  • 我可以通过在执行其中一个函数时添加无限递归来模拟该问题,从而测试EXCEPTION_STACK_OVERFLOW异常的捕获.
  • 我将WinDBG设置为崩溃转储程序,并获取所有其他崩溃问题的良好信息,但不是这个.崩溃转储只包含一个线程,即'Sleep()'.所有其他线程已退出.

问题

我尝试的所有事情都没有导致EXCEPTION_STACK_OVERFLOW异常.

有没有人知道如何保证在发布模式的运行时期间有机会获得此异常?

定义

  1. Poof-Crash:应用程序因"poof"崩溃而消失得无影无踪.

(考虑到这个网站的名称,我有点惊讶这个问题已不在这里了!)

笔记

  1. 简要介绍了有关调整堆栈大小的答案,以便更快地强制解决问题并允许使用调试器捕获它.这是一个聪明的想法,但不幸的是,我不相信它会有所帮助.这个问题很可能是由一个导致无限递归的极端情况引起的.缩短堆栈不会更快地暴露问题,并且可能导致有效深度代码中的无关崩溃.不错的想法,并感谢发布它,即使你删除它.

c++ stack-overflow debugging exception-handling structured-exception

6
推荐指数
1
解决办法
2605
查看次数

将外部错误代码映射到std :: error_condition

我正在考虑修改MS结构化异常到异常映射代码,我们必须使用新的C++ 11 error_code/error_condition/exception mechanisim.

我的理解是,一般的哲学是你应该首先尝试将你的错误代码映射到std :: error_condition代码,否则,制作你自己的自定义error_condition代码.

我看到的问题是std :: errc非常适合与POSIX错误配合使用.如果我从一个源代码中获取代码,该代码具有与典型OS调用相比差异很大的错误,那么它就不能很好地映射.

例如,我们可以使用Microsoft的SEH代码.这些来自操作系统,所以理论上它应该映射以及POSIX之外的任何东西.但它肯定似乎没有很好地映射:

EXCEPTION_ACCESS_VIOLATION  = permission_denied
EXCEPTION_ARRAY_BOUNDS_EXCEEDED = argument_out_of_domain perhaps?
EXCEPTION_BREAKPOINT = ?
EXCEPTION_DATATYPE_MISALIGNMENT = ?
EXCEPTION_FLT_DENORMAL_OPERAND = ? 
EXCEPTION_FLT_DIVIDE_BY_ZERO = ?
EXCEPTION_FLT_INEXACT_RESULT = ? 
EXCEPTION_FLT_INVALID_OPERATION = ?
EXCEPTION_FLT_OVERFLOW = ?
EXCEPTION_FLT_STACK_CHECK = ?
EXCEPTION_FLT_UNDERFLOW = ?
EXCEPTION_GUARD_PAGE = ?
EXCEPTION_ILLEGAL_INSTRUCTION = ?
EXCEPTION_IN_PAGE_ERROR = ?
EXCEPTION_INT_DIVIDE_BY_ZERO = ?
EXCEPTION_INT_OVERFLOW = value_too_large perhaps, but then what do I use for _STACK_OVERFLOW?
EXCEPTION_INVALID_DISPOSITION = ?
EXCEPTION_INVALID_HANDLE = ? …
Run Code Online (Sandbox Code Playgroud)

c++ structured-exception c++11

5
推荐指数
1
解决办法
1014
查看次数

如何通过COM公开结构化异常处理捕获的异常?

我在Visual C++中实现的COM服务器使用了大量其他C++代码.其他C++代码有时会包含代码__try- __except并将结构化异常转换为自定义C++异常.这部分我无法改变.

我的COM服务器的任何方法都不应该允许这些异常通过COM边界传播,因此它必须捕获并将它们转换为HRESULTs.这些自定义C++异常包含在翻译期间获得的原始错误代码 - 它就像是EXCEPTION_ACCESS_VIOLATION.问题是我如何设计一个合适的HRESULT值,以便客户端尽可能多地获得有关发生的事情的信息(并且可能在看到访问冲突后决定重新启动服务器(以及在inproc的情况下).

假设它是EXCEPTION_ACCESS_VIOLATION在中定义的WinBase.h

#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
Run Code Online (Sandbox Code Playgroud)

而后者的定义是 WinNT.h

#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005L)
Run Code Online (Sandbox Code Playgroud)

我可以使用它HRESULT_FROM_WIN32()来转换代码,HRESULT假设它首先是一个Win32错误.

HRESULT_FROM_WIN32()在这里使用还是以其他方式进行翻译?

c++ com winapi structured-exception visual-c++

5
推荐指数
1
解决办法
207
查看次数

混合c ++异常处理和SEH(windows)

我有一个函数,我调用它getaddrinfo()来获取sockaddr*系统分配的目标内存.许多人可能知道,你需要调用freeaddrinfo()来释放getaddrinfo()分配的内存.

现在,在我的函数中,有一些地方,我可能会抛出异常,因为某些函数失败了.我的第一个解决方案是将freeaddrinfo()每个if块整合到一起.但对我来说这看起来确实很难看,因为在我的函数返回之前我不得不调用它,所以我想出了SEH的尝试 - 终于......

但我遇到的问题是,不允许将throw语句编码到__try-block中

然后,我读了msdn并尝试将throw语句交换到__try-block中调用的辅助函数...瞧,编译器不再呻吟了......

这是为什么?这样安全吗?这对我来说没有意义:/

码:

void function()
{
    //...
    addrinfo* pFinal;
    __try
    {
        getaddrinfo(..., &pFinal);

        //if(DoSomething1() == FAILED)
        //  throw(exception);           //error C2712: Cannot use __try in functions that require object unwinding

        //but this works
        Helper();


        //...

    }
    __finally
    {
        freeaddrinfo();
    }
}


void Helper()
{
    throw(Exception);
}
Run Code Online (Sandbox Code Playgroud)

编辑:

尝试了下面的内容,它可以抛出一个整数,但是当我使用一个类作为例外时却不行:

class X
{
public:
    X(){};
    ~X(){};
};


void Helper()
{
    throw(X());
}


void base()
{
    __try
        {
            std::cout << "entering …
Run Code Online (Sandbox Code Playgroud)

c++ exception-handling seh structured-exception

5
推荐指数
2
解决办法
2559
查看次数

结构化异常处理程序 (SEH) 无法捕获堆损坏

我正在编写一个小型实用程序(VC 2010,无 clr),它使用第 3 方库执行一项简单的任务(光栅化)。稍后的实用程序将被更大的应用程序使用。有时,该实用程序会因第 3 方库中的某些堆损坏而崩溃。没关系,但 Windows (Vista/2008) 显示众所周知的对话框“程序已停止工作...关闭/调试程序”。这不适合我的情况(服务器端)。实用程序应该静默地崩溃/终止,没有任何可见的影响。

为此,我为未处理的异常安装了 SEH (SetUnhandledExceptionFilter)。对于 AV ( *(PDWORD)0 = 0 ) 等异常,可以完美调用该处理程序,但由于某种原因,在堆损坏的情况下不会调用该处理程序。卸载第 3 方库 dll 之一的 dllmain 时发生损坏。

有几个问题。谁能解释为什么不调用处理程序?还有其他方法可以阻止该对话框吗?

c++ exception seh structured-exception heap-corruption

5
推荐指数
1
解决办法
4415
查看次数

'get'相当于_set_se_translator?

我需要使用当前翻译手动翻译结构化异常.

我如何"获得"某人设定的价值_set_se_translator

c++ winapi seh structured-exception visual-c++

2
推荐指数
1
解决办法
681
查看次数