Structured Exception Handling (C/C++)

SEH(구조적 예외 처리)는 하드웨어 오류와 같은 특정 예외 코드 상황을 정상적으로 처리하기 위해 C 및 C++에 대한 Microsoft 확장입니다. Windows 및 Microsoft C++는 SEH를 지원하지만 C++ 코드에서 ISO 표준 C++ 예외 처리를 사용하는 것이 좋습니다. 코드를 더 이식 가능하고 유연하게 만듭니다. 그러나 기존 코드 또는 특정 종류의 프로그램을 기본 위해 SEH를 사용해야 할 수 있습니다.

Microsoft 전용:

문법

try-except-statement :
__try compound-statement __except ( filter-expression ) compound-statement

try-finally-statement :
__try compound-statement __finally compound-statement

설명

SEH를 사용하면 실행이 예기치 않게 종료될 경우 메모리 블록 및 파일과 같은 리소스가 올바르게 해제되도록 할 수 있습니다. 문이나 반환 코드의 정교한 테스트에 의존 goto 하지 않는 간결한 구조화된 코드를 사용하여 특정 문제(예: 메모리 부족)를 처리할 수도 있습니다.

try-except 문서에서 참조하는 명령문 및 try-finally 문은 C 및 C++ 언어에 대한 Microsoft 확장입니다. 둘 다 애플리케이션이 그렇지 않을 경우 실행을 종료하는 이벤트 후에 프로그램을 제어할 수 있도록 하여 SEH를 지원합니다. SEH는 C++ 소스 파일에서 작동하지만 C++용으로 특별히 설계된 것은 아닙니다. 또는/EHsc옵션을 사용하여 컴파일하는 C++ 프로그램에서 SEH를 사용하는 /EHa 경우 로컬 개체에 대한 소멸자가 호출되지만 다른 실행 동작은 예상과 다를 수 있습니다. 일러스트레이션은 이 문서의 뒷부분에 있는 예제를 참조하세요. 대부분의 경우 SEH 대신 ISO 표준 C++ 예외 처리를 사용하는 것이 좋습니다. C++ 예외 처리를 사용하면 코드 포팅 가능성이 향상되며 모든 형식의 예외를 처리할 수 있습니다.

SEH를 사용하는 C 코드가 있는 경우 C++ 예외 처리를 사용하는 C++ 코드와 혼합할 수 있습니다. 자세한 내용은 C++의 구조적 예외 처리를 참조 하세요.

SEH 메커니즘에는 다음 두 가지가 있습니다.

이러한 두 종류의 처리기는 고유하지만 스택 해제라고 하는 프로세스를 통해 밀접하게 관련됩니다. 구조적 예외가 발생하면 Windows는 현재 활성 상태인 가장 최근에 설치된 예외 처리기를 찾습니다. 처리기는 다음 세 가지 작업 중 하나를 수행할 수 있습니다.

  • 예외를 인식하지 못하고 컨트롤을 다른 처리기(EXCEPTION_CONTINUE_SEARCH)에 전달합니다.

  • 예외를 인식하지만 해제합니다(EXCEPTION_CONTINUE_EXECUTION).

  • 예외를 인식하고 처리합니다(EXCEPTION_EXECUTE_HANDLER).

예외가 발생할 때 실행 중이던 함수에 예외를 인식하는 예외 처리기가 없을 수 있습니다. 스택에서 훨씬 더 높은 함수에 있을 수 있습니다. 현재 실행 중인 함수 및 스택 프레임의 다른 모든 함수가 종료됩니다. 이 프로세스 중에 스택이 해제됩니다. 즉, 종료된 함수의 로컬 비정적 변수가 스택에서 지워집니다.

스택을 해제할 때 운영 체제는 각 함수에 대해 작성된 종료 처리기를 모두 호출합니다. 종료 처리기를 사용하면 비정상적인 종료로 인해 다시 열려 기본 리소스를 클린. 중요한 섹션을 입력한 경우 종료 처리기에서 종료할 수 있습니다. 프로그램이 종료되는 경우 임시 파일 닫기 및 제거와 같은 다른 하우스키핑 작업을 수행할 수 있습니다.

다음 단계

예시

앞에서 설명한 것처럼 C++ 프로그램에서 SEH를 사용하고 또는 /EHsc 옵션을 사용하여 /EHa 컴파일하는 경우 로컬 개체에 대한 소멸자가 호출됩니다. 그러나 C++ 예외를 사용하는 경우 실행 중 동작이 예상과 다를 수 있습니다. 이 예제에서는 이러한 동작 차이점을 보여 줍니다.

#include <stdio.h>
#include <Windows.h>
#include <exception>

class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\n");
    }
};

__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}

__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}

int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\n");
    }

    return 0;
}

이 코드를 컴파일하는 데 사용 /EHsc 하지만 로컬 테스트 제어 매크로 CPPEX 가 정의 TestClass 되지 않은 경우 소멸자가 실행되지 않습니다. 출력은 다음과 같습니다.

Triggering SEH exception
Executing SEH __except block

코드를 CPPEX 컴파일하는 데 사용하고 /EHsc C++ 예외가 throw TestClass 되도록 사용하여 /DCPPEX 정의되는 경우 소멸자가 실행되고 출력은 다음과 같이 표시됩니다.

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

코드를 TestClass 컴파일하는 데 사용하는 /EHa 경우 소멸자가 표준 C++ throw 식을 사용하거나 SEH를 사용하여 예외가 throw되었는지 여부를 실행합니다. 즉, 정의되었는지 여부 CPPEX 입니다. 출력은 다음과 같습니다.

Throwing C++ exception
Destroying TestClass!
Executing SEH __except block

자세한 내용은 (예외 처리 모델)을 참조 /EH 하세요.

END Microsoft 전용

참고 항목

예외 처리
키워드
<exception>
오류 및 예외 처리
구조적 예외 처리(Windows)