본문 바로가기
프로그래밍/C·C++

SEH(Structured Exception Handling)

by ITPro 2011. 8. 15.

참조 : http://msdn.microsoft.com/en-us/library/swezty51(v=VS.71).aspx

비동기적으로 아무 때나 발생가능한 인터럽트와 달리 실행 중인 프로그램의 직접적인 실행 결과로 발생하는 예외를 처리하기위하여 윈도우는 어플리케이션이 예외 발생시 제어를 받을 수 있도록 SEH를 사용한다.
SEH는 시스템 메커니즘으로서 프로그램 언어 한정적인 것이 아니라 것에 유의해야한다. 
※여기에서는 C를 기준으로 사용법을 기술한다.

SEH는 기능적 특성에 따라 Termination Handler와 Exception Handler 두 가지로 나뉜다.

1.Termination Handler
Termination Handler는 __try와 __finally 키워드로 구성되며 __try 블록의 코드가 실행이 되면 프로세스가 종료되지 않는 한 반드시 __finally 블록의 코드가 실행이 된다.
__finally 블록의 내용으로는 예외 발생과는 무관하게 반드시 해제해야하는 메모리, 핸들, 동기화 오브젝트 등에 대한 처리 코드가 들어간다.

2.Exception Handler
Exception Handler는 Termination Handler가 __finally 블록의 코드를 무조건적으로 실행하는 것에 반해  __except 블록의 코드가 필터에 의해 선별적인 실행된다는 차이점이 있다.
__except 블록의 필터는 세가지가 존재한다.

필터
 EXCEPTION_EXECUTE_HANDLER 1
 EXCEPTION_CONTINUE_EXECUTION -1
 EXCEPTION_CONTINUE_SEARCH -1

2-1.EXCEPTION_EXECUTE_HANDLER
__try 블록 내부에서 예외가 발생하면 __try 블록을 빠져나와 __except 블록 코드를 실행한다.

2-2.EXCEPTION_CONTINUE_EXECUTION
__try 블록 내부에서 예외가 발생하면 __try 블록을 빠져나와 __except 블록 코드를 실행한 뒤, 다시 __try 블록으로 이동하여 예외가 발생한 코드부터 다시 실행한다.
__except 블록에 예외 보정 코드가 들어있지 않다면 프로세스가 무한 루프에 빠진다.

2-3.EXCEPTION_CONTINUE_SEARCH
__try 블록 내부에서 예외가 발생하면 상위 예외 핸들러를 찾아서 예외를 처리한다.

2-4.관련 함수
-GetExceptionInformation() : 예외 정보를 EXCEPTION_POINTERS 구조체 포인터로 반환한다.
-GetExceptionCode() : 예외 내용을 INT 값으로 반환한다.
예외 코드 내용
 STATUS_ACCESS_VIOLATION 접근할 수 없는 메모리 영역에 R/W를 시도한 경우
 STATUS_BREAKPOINT 하드웨어 브레이크 포인트를 만난 경우 (디버거에서만 사용)
 STATUS_DATATYPE_MISALIGNMENT 제대로 정렬되어 있지 않은 주소의 데이터에 R/W를 시도한 경우
 STATUS_FLOATING_DIVIDE_BY_ZERO floating-point를 0.0으로 나누려고 시도한 경우
 STATUS_FLOATING_OVERFLOW floating-point의 표현가능한 최대값을 넘어선 경우
 STATUS_FLOATING_UNDERFLOW floating-point의 표현가능한 최소값을 넘어선 경우
 STATUS_FLOATING_RESEVERED_OPERAND reserved floating-point 포맷을 사용한 경우
 STATUS_ILLEGAL_INSTRUCTION 프로세서에 정의되어있지 않은 명령을 실행하려고 시도한 경우
 STATUS_PRIVILEGED_INSTRUCTION 현재 Machine mode에서 사용할 수 없는 명령을 실행하려고 시도한 경우
 STATUS_INTEGER_DIVIDE_BY_ZERO integer를 0으로 나누려고 시도한 경우
 STATUS_INTEGER_OVERFLOW integer의 범위를 넘는 명령을 실행하려고 시도한 경우
 STATUS_SINGLE_STEP 명령을 single-step mode로 실행한 경우 (디버거에서만 사용)


3.예제
3-1.MSDN 예제 코드 (http://msdn.microsoft.com/en-us/library/s58ftw19(v=VS.71).aspx)
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements

#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>

int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
 

   puts("in filter.");
   if (code == EXCEPTION_ACCESS_VIOLATION) {
      puts("caught AV as expected.");
      return EXCEPTION_EXECUTE_HANDLER;
   }
   else {
      puts("didn't catch AV, unexpected.");
      return EXCEPTION_CONTINUE_SEARCH;
   }
}

int main()
{
   int* p = 0x00000000;   // pointer to NULL
   puts("hello");
   __try{
      puts("in try");
      __try{
         puts("in try");
         *p = 13;    // causes an access violation exception;
      }__finally{
         puts("in finally. termination: ");
         puts(AbnormalTermination() ? "\tabnormal" : "\tnormal");
      }
   }__except(filter(GetExceptionCode(), GetExceptionInformation())){
      puts("in except");
   }
   puts("world");
}


3-2.실행결과
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
        abnormal
in except
world 
 

반응형

'프로그래밍 > C·C++' 카테고리의 다른 글

VEH (Vectored Exception Handling)  (0) 2011.08.15
strrstr 함수 구현 (문자열 역순 탐색 함수)  (0) 2011.07.20
프로세스 리스트 얻기  (0) 2011.07.04
프로세스 제거하기  (0) 2011.07.04
프로세스 생성하기  (0) 2011.07.04