이번에 얘기할 부분은 예외 발생시 OS(windows)가 주는 정보를 활용하여 예외처리를 하는 방법에 대해 말하겠다.



GetExceptionInfomation(VOID) 함수는 EXCEPTION_POINTERS* 를 돌려준다.


이 함수는 예외처리 필터안에서만 호출되어야 한다. 그 이유는 EXCEPTION_POINTERS 내부에 존재하는 CONTEXT, EXCEPTION_RECORD,EXCEPTION_POINTERS 자료구조는 예외필터가 처리되는 동안만 유요하기 때문이다.



EXCEPTION_RECORD 의 정보.


 .ExceptionCode : 예외상황 코드로서 GetExceptionCode()가 반환하는 정보와 같다.


 .ExceptionFlag : 예외상황에 대한 플래그이며 현재는 두개의 값이 존재한다. 예외상황을  나타내는 0과 계속되지 않는 예외상황을 나타내는 EXCEPTION_NOCONTINUABLE값이다. 계속되는 예외상황 다음에 실행을 계속하는 거은 EXCEPTION_NONOCONTINUABLE_EXCEPTION 예외상황을 일으킨다.


 .ExceptionRecord : 다른 처리되지 않은 예외상황을 위한 EXCEPTION_RECORD 구조를 포인트한다. 예외상황을 처리하는 동안 예외필터 안에서 예외를 만나는 경우에  이 값을 활성화 되며, 예외처리중 예외상황이 발생하지 않으면 이값은 NULL을 가진다.


 .Exception Address : 예외상황을 발생시킨 CPU명령의 주소를 알려준다.


 .NumberParameters : 예외상황과 연관된 파라메터의 수를 알려준다(0~15) 대부분 0이다.


 .ExceptionInfomation : 예외상황을 명시하는 추가적 인자의 배열이다. 거의 모든 예외상황에서 배열원소는 정의되지 않는다.



NumberParameters와 ExceptionInfomation은 예외 필터에게 예외상황에 대해 좀 더 추가적인 정보를 제공하지만, 현재는 EXCEPTION_ACCESS_VIOLATION에 대한 추가정보를 제공한다. 예외가 발생했을시 NumberParameters 해당 값이 존재하면 추가정보를 확인하면 된다.

처리되지 않은 예외상황


모든 예외 필터가 EXCEPTION_CONTINUE_SEARCH를 리턴하게 되면 어떤 상황이 발생할까? 이런 상황을 처리되지 않은 예외상황이라 부른다. 실제 이런식일이 일어나면 프로그램은 어떻게 될까?



모든 스레드는 Kernel32.dll 안의 BaseProcessStart또는 BaseThreadStart의 함수를 실행하면서 실행된다. 이 두 함수의 내부에 SEH가 존재하며 예외처리 필터에는 UnhandledExceptionFilter(GetExceptionInfomation())을 호출하며 후에 ExitProcess(GetExceptionCode())를 호출한다.



LONG UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)



이 함수는 프로세스에게 스레드에서 처리되지 않은 예외상황이 발생했다는 메시지 박스를 보여주며 사용자에게 중단 또는 디버그를 할수있도록 해주는 역할을 한다.



모든 스레드의 함수들을 SEH로 감싸기



SEH구조에 있는 모든 스레드 함수들을 감쌀수(wrap)있는 함수를 제공한다.



PTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter(PTOP_LEVEL_EXCEPTION_FILTER pTopLevelExceptionFilter);



프로세스가 이 함수를 호출한 이후 프로세스의 스레드에서 처리되지 않은 예외상황이 발생하면 SetUnhandledExceptionFilter 의 인자로 넘긴 함수가호출된다. 필터 함수의 프로토타입은


LONG UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)


위와 같다.

Post to Twitter