반응형


http://3dmpengines.tistory.com/614 에도 SEH 에 대해 올린글이 있음







구조적 예외 처리 - Structured Exception Handling(SEH)  Window 

2011/08/01 11:14

복사http://blog.naver.com/yoonga87/10114826647





일반적으로 c++에서 사용하는 예외처리 문법에는 try, catch, throw이 있다. 하지만 windows c++환경에서 사용되는 또 하나의 예외처리 문법이 있는데, __try, __except, __finally가 그것이다. 이 둘의 차이점은 분명하게 나누어진다. try, catch, throw는 사용자 애플리케이션 단위의 예외처리 문법이라면 __try, __except, __finally는 windows 운영체제 단위의 예외처리 문법이다. try, catch, throw는 내부적으로 __try, __except, __finally를 사용해 구현된다.

 

일반적으로 운영체제(os) 단위에서 발생하는 예외로는 null pointer 참조나 0나누기를 들 수 있다. 이런 운영체제 단위의 예외를 처리하고 싶을 때 c++에서 사용하는 예외처리기가 아닌 os 단위의 예외처리기를 사용해야 한다.

 

__try, __except, __finally의 기본적인 문법은 다음과 같다.

 

__try

{

...

 //예외를 감시할 루틴

...

}

__except( 예외 필터 )

{

...

//예외 처리

...

}

 

__try

{

...

return; // return이 발생해도 __finally는 실행됨.

}

__finally

{

// 무조건 실행해야하는 루틴

}

 

여기서 주의해야 할 점은 __except와 __finally는 하나의 __try블록에 같이 쓸 수 없다는 점이다.

 

__except 안에 들어가는 예외 필터에는 다음과 같이 3가지가 있다.

EXCEPTION_EXECUTE_HANDLER

EXCEPTION_CONTINUE_SEARCH

EXCEPTION_CONTINUE_EXECUTION

 

* EXCEPTION_EXECUTE_HANDLER

 

예외가 발생한 지점에서 빠져나와 __except 안에있는 루틴을 실행한다. __except 안에 있는 루틴의 실행이 끝나면 계속해서 다음 루틴을 실행해 나간다.

 

* EXCEPTION_CONTINUE_SEARCH

 

예외가 발생한 지점에서 빠져나와 call stack에서 다음 __try 블록을 찾는다. 만약 __try를 못찾으면 kernel에게 예외가 보내지고 에러메시지와 함께 application이 비정상종료하게 된다.

 

* EXCEPTION_CONTINUE_EXECUTION

 

예외가 발생한 지점을 다시 실행한다. 만약 다시 실행할 때 문제가 해결된 상태가 안된다면 무한 루프를 돌게 된다.

 

이 3가지 예외 필터의 순서도를 그려보면 다음과 같다.

 

 







http://ezbeat.tistory.com/122




DWORD GetExceptionCode(void);

예외가 발생했을 때 어떠한 종류의 예외가 발생했는지를 확인하기 위해서 사용

example code)
__except(EXCEPTION_CONTINUE_HANDLER){
DWORD exptType = GetExceptionCode();

switch( exptType )
{
case EXCEPTION_ACCESS_VIOLATION:
_tprintf(_T(" Access violation \n\n"));
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
_tprintf(_T(" Divide by zero \n\n"));
break;
}
}

EXCEPTION_ACCESS_VIOLATION     (0xC0000005) 메모리 참조 오류를 구분하기 위해서 정의해 놓은 정수값
EXCEPTION_INT_DIVIDE_BY_ZERO  (0xC0000094) 정수를 0으로 나누는 예외를 너타내기 위해 정의해 놓은 정수값
EXCEPTION_BREAKPOINT             (0x80000003) 중단점 발생하면!

위 함수보다 더욱 자세하게 예외에 대한 내용을 알고 싶다면
LPEXCEPTION_POINTERS GetExceptionInformation(void);
함수를 호출한다.

구조체 주소를 리턴한다. EXCEPTION_POINTERS구조체를 봐보겠다.

typedef struct _EXCEPTION_POINTERS {
  PEXCEPTION_RECORD ExceptionRecord; //예외에 대한 정보가 담김
  PCONTEXT          ContextRecord; //프로세서의 레지스터 데이터를 비롯한 프로세서의 종속적인 정보
} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;

typedef struct _EXCEPTION_RECORD {
  DWORD                    ExceptionCode; //RaiseException함수의 첫번째 인자가 들어옴
  DWORD                    ExceptionFlags; //두번째 인자
  struct _EXCEPTION_RECORD *ExceptionRecord;
  PVOID                    ExceptionAddress;
  DWORD                    NumberParameters; //세번째 인자
  ULONG_PTR                ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //네번째 인자
} EXCEPTION_RECORD, *PEXCEPTION_RECORD;


반응형

+ Recent posts