728x90

예외 핸들러

- __try 블럭과 __except(예외 처리 방식) 블럭으로 이루어 짐

- __try과 __except는 하나의 구문으로 이해해야 함

- __try에서 발생한 예외는 __except에서 처리

- __try에서 예외가 발생하면 __except()로 이동하고 예외 처리 방식에 맞게 예외 처리가 진행됨

- __except(예외 처리 방식)에서 예외 처리 방식(필터)은 아래 3가지 중 하나를 넣어야 함

    -> EXCEPTION_EXCUTE_HANDLER : 예외 처리 후 except의 블럭을 실행하고 try에서 예외가 발생된 이후의 코드는 실행하지 않음

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(int argc, TCHAR* argv[])
{
	_tprintf(_T("start\n"));
	int* p = NULL;
	__try
	{
		*p = 100;	// 예외 발생
		_tprintf(_T("value : %d \n"), *p);
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		_tprintf(_T("exception occurred!\n"));
	}
	_tprintf(_T("end\n"));
	return 0;
}

    -> EXCEPTION_CONTINUE_EXECUTION : __except 블럭을 실행하지 않고 예외가 발생한 지점에서 다시 실행

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int a, b;

DWORD FilterFunction(DWORD exptType)
{
	switch (exptType)
	{
	case EXCEPTION_INT_DIVIDE_BY_ZERO:
		_tprintf(_T("Wrong Number inserted \n"));
		_tprintf(_T("input b : "));
		_tscanf("%d", &b);
		return EXCEPTION_CONTINUE_EXECUTION;
	}
}
int _tmain(int argc, TCHAR* argv[])
{
	_tprintf(_T("start\n"));
	__try
	{
		_tprintf(_T("input a, b : "));
		_tscanf("%d %d", &a, &b);
		_tprintf(_T("value : %d \n"), a / b);
	}
	__except(FilterFunction(GetExceptionCode()))
	{
		_tprintf(_T("except occured"));
	}
	_tprintf(_T("end\n"));
	return 0;
}

    -> EXCEPTION_CONTINUE_SEARCH : 예외가 발생하면 그 함수를 리턴하고 상위 함수의 __except에서 예외를 처리

 

처리되지 않은 예외의 이동

void Divide(int a, int b)
{
  _tprintf(_T("a = %d b = %d"),a,b);
}

__try
{
  switch(sel)
  {
    case DIV:
      Divide(num1, num2);
      break;
    ...
  }
}
__except(EXCEPTION_EXUCTE_HANDLER)
{
  _tprintf(_T("end"));
}
  

- 위 상황에서 Divide 함수에 인자로 10, 0이 주어지면 H/W 예외가 발생하게 됨

- Divide 함수에는 __try, __except이 없기 때문에 함수가 반환되어 버림

- 예외가 처리되지 않았기 때문에 상위 함수에서 __try 블럭을 찾게 되고 __except에서 예외가 처리가 됨

- 만약 __try가 상위 함수에서도 없다면 운영체제로 넘어가게 되고 운영체제는 프로그램을 종료시켜 버림

 

예외를 구분하는 방법

- GetExceptionCode() 

    -> 예외가 왜 일어났는지 알수 있는 방법

    -> 반환 값

728x90

+ Recent posts