posted by 초식사자 2011.08.15 01:11

참조 : 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
SEH(Structured Exception Handling)  (0) 2011.08.15
strrstr 함수 구현 (문자열 역순 탐색 함수)  (0) 2011.07.20
프로세스 리스트 얻기  (0) 2011.07.04
프로세스 제거하기  (0) 2011.07.04
프로세스 생성하기  (0) 2011.07.04

댓글을 달아 주세요