SEH 란?
SEH란 Window에서 지원하는 예외처리 방식으로서 런타임시 프로그래머가 의도치 않게 발생하는 오류에 대비하는 장치이다.
SEH 의 구조.
1. try ~ finally 구조

이 구조는 __try 내부의 코드를 실행중이였다면 무슨일이 생겨도(__leave를 만나지않는한) __finally내부의 코드를 실행할수있다.
무슨 의미냐면, __try내부의 코드가 정상적으로 실행된 후에 __finally 내부의 코드를 실행할수 있으며, __try내부의 코드를 실행중 예외(기본적인 메모리 침범같은것들)가 발생해도 예외처리가 되었다면 __finally 내부의 코드를 실행한다. 만약 __try 내부 코드중에 __leave키워드를 만나게 되면 다음번에 실행되는 코드는 __leave하단에 위치한코드가 아닌 __finally블럭다음의 코드를 실행하게된다. (한마디로 __leave를 만나면 __finally를 건너띄게 된다)
2. try ~ except 구조

이 구조는 __try 내부의 코드를 실행중 예외가 발생시 __except내부의 인자값에 따라 처리하는 방식이 달라진다.
1. EXCEPTION_EXECUTE_HANDLER : 이 값을 인자로 넘기게 되면 Global Unwind가 일어나며 프로그램의 실행은 __except블럭 (예외 핸들러) 내부로 진입한다. 블럭 내부의 코드가 실행이 되고 나면 해당 코드는 __except 블럭 뒤의 코드를 실행하게 된다.
2. EXCEPTION_CONTINUE_EXECUTION : 이 값을 인자로 넘기게 되면 예외상황을 발생시킨 구문으로 다시 돌아가서 해당 구문을 다시 실행하게 된다.
3. EXCETPION_CONTINUE_SEARCH : 이 값을 인자로 넘기게 되면 현재 try ~ except 구문 밖에 있는 try ~ except 구문으로 제어권을 넘기게 된다.
. 부가적인 정보를 얻는 방법
예외 상황이 발생하였을 경우 해당 예외가 어떤 예외 상황을 나타내는지 알수있는 함수가 있다. DWORD GetExceptionCode() 이며, 예외의 종류는 winbase.h 안에 정의 되어있다.
◎ 메모리 관련 예외 상황
.EXCEPTION_ACCESS_VIOLATION : 접근이 허가되지 않은 메모리를 읽거나 쓸경우
.EXCEPTION_DATATYPE_MISALIGNMENT : 정렬을 제공하지 않는 하드웨어에 정렬되지 않는 데이터를 읽거나 쓰는 작업을 시도했을경우
.EXCEPTION_ARRAY_BOUNDS_EXCEEDED : 배열에서 범위를 벗어난 원소에 접근하고자 했을 경우
.EXCEPTION_IN_PAGE_ERROR : 파일 시스템이나 장치 드라이버가 읽기 에러를 리턴했기 때문에 페이지 실패는 만족될 수 없다. (무슨 의미인지. -_-ㅋ)
.EXCEPTION_GUARD_PAGE : PAGE_GUARD 속성이 걸린 메모리 페이지에 접근을 시도했을경우. (페이지가 접근 가능하게 만들어지면 EXCEPTION_GUARD_PAGE 예외상황발생)
.EXCEPTION_STACK_OVERFLOW : 할당된 스택을 모두 사용했을 경우
.EXCEPTION_ILLEGAL_INSTRUCTION : 유효치 않은 명령어를 실행했을 경우.
.EXCEPTION_PRIV_INSTRUCTION : 현재 기계 상태에서 실행할수 없는 연산을 실행하고자 했을 경우.
◎ 예외상황 관련 예외 상황
.EXCEPTION_INVALID_DISPOSITION : 예외 필터가 EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_CONTINUE_EXECUTION 가 아닌 다른 값을 주었을 경우.
.EXCEPTION_NONCONTINUABLE_EXCEPTION : 예외 필터가 계속할 수 없는 예외 상황에 반응하여 EXCEPTION_CONTINUE_EXECUTION 값을 주었을 경우
◎ 디버깅 관련 예외 상황
.EXCEPTION_BREAKPOINT : 중단점을 만났을 경우.
.EXCEPTION_SINGLE_STEP : 추적 트랩이나 단일 명령 매커니즘이 하나의 명령어가 실행되었다고 알려줄때 발생
.EXCEPTION_INVALID_HANDLE : 함수가 잘못된 핸들을 파라메터를 받을때 발생한다
◎ 정수관련 예외 상황
.EXCEPTION_INT_DIVIDE_BY_ZERO : 어떤 정수를 0으로 나누고자 했을때 발생.
.EXCEPTION_INT_OVERFLOW : 연산후 결과값에서 맨 왼쪽 비트가 다음 비트로 오버하는 현상이 발생했을때.
◎ 부동 소수점 관련 예외 상황
.EXCEPTION_FLT_DENORMAL_OPERAND : 부동소수점 연산시 피연산자가 denormal일때 발생(denormal : 표준 부동소수점 값을 나타내기에 너무 적은 값)
.EXCEPTION_FLT_DIVIDE_BY_ZERO : 부동소수점을 0으로 나누고자 했을경우.
.EXCEPTION_FLT_INEXACT_RESULT : 부동소수점 연산결과가 소수로 정확히 표현되지 않을경우 발생.
.EXCEPTION_FLT_OVERFLOW : 부동소수점 연산의 지수가 대응하는 타입에 허용되는 크기보다 클경우 발생.
.EXCEPTION_FLT_STACK_CHECK : 부동소수점 연산으로 인해 스택 오버플로우나 스택 언더 플로우가 발생했을 경우
.EXCEPTION_FLT_UNDERFLOW : 부동소수점 연산의 지수가 타입에 허용되는 크기보다 작을때 발생.
.EXCEPTION_FLT_INVALID_OPERATION : 여기에 표시되지않은 부동소수점관련 예외상황발생시

처음 뵙겠습니다. (__);;
try, finally, leave에 대해서 알아보다가 이곳까지 들어오게 되었습니다.
근데 leave에 대한 설명이 약간 잘못된게 아닌가 싶어서 글을 남기게 되었습니다. 테스트 프로그램을 돌려 보니 try 안에서 leave를 만나도 finally를 안거치는 것이 아니라 finally를 거친 후 빠져나가는 것을 확인했습니다. 이 부분 확인 한번 부탁드리겠습니다. ^^;
좋은 글 감사합니다.
| 2010-03-16 @ 6:47 오전
아 글이 잘못 적혀있네요 @_@
알려주셔서 감사합니다. ^^
| 2010-03-16 @ 7:13 오전