Transcript Document
CGCII
Cho sanghyun’s Game Classes II
Executor with Exception
CGCII
예외처리
SEH란?
Cho sanghyun’s Game Classes II
Structured Exception Handling
SEH(Structured Exception Handling)은 윈도즈 O/S 차원의 예외 처리 시스템이다.
SEH는 C++ Exception과 별개이며 언어 중립적이다.
(C++의 try, catch에는 잡히지 않는다.)
C++ Exception
try
throw
catch
일반적으로
SEH
__try
__ exception
__finally
‘뻑!’났을 때 덤프 남기는 용도로 많이 사용한다!!
(Divide by zero, Access Violation at …! 등등)
보통 SEH의 사용은 여기까지다.
덤프 남기는 것만으로도 감사 감사~
CGCII
예외처리
SHE란?
Cho sanghyun’s Game Classes II
그렇다면!
SEH로 Windows System Exception만
무모화 시킨다면 다운 없는 서버!!!?
오히려 더 큰일난다!
→ 예외 중립 훼손
(즉 뻑! 났는지도 모르고 아무런 처리도 없이 그냥 넘기면 더 큰일남)
하지만 C++ Exception 보장 처리와 SEH를 연동 처
리하면 뻑이 나도 다운되지 않고 안전하게 동작 가능한 서버
를 만들 수 있다.
CGCII
예외처리
SEH와 C++ Exception의 결합
Cho sanghyun’s Game Classes II
Visual C++의 Project의 Property에서 /EHa 옵션을 설정한다.
즉 C++ Exception과 SEH가 연동될 수 있도록 옵션을 설정한다.
CGCII
예외처리
SEH 사용 (1)
Cho sanghyun’s Game Classes II
보통 뻑이 나면 Mini-Dump를 남기는 용도로만 사용한다.
void fSEHTranslator(unsigned int, LPEXCEPTION_POINTERS p_pException)
{
…
CreateDump(p_pException);
…
printf(“뻑났슈!!! 코딩 이렇게 밖에 못해?!!”);
}
void main()
{
// 쓰레드마다 설정해 주어야 한다.
_set_se_translator(&fSEHTranslator);
…
// 뻑 유발자 코드 (처리 중 뻑나면 fSEHTranslator 함수를 실행할 것이다!)
*(int*)0 = 10;
}
CGCII
예외처리
SEH와 C++ 예외의 결합
Cho sanghyun’s Game Classes II
C++ Exception과 함께 사용하면 좀더 다른 처리가 가능하다.
void fSEHTranslator(unsigned int, LPEXCEPTION_POINTERS p_pException)
{
CreateDump(p_pException);
throw
std::exception();
2. C++ Exception을 던진다!!!!
}
void main()
{
// 쓰레드마다 설정해 주어야 한다.
_set_se_translator(&fSEHTranslator);
1. 여기서 ‘뻑’난다!!!
…
try
{
(이 순간 C++ Exception이 발생하지 않고 SEH에 의해...)
// 뻑 유발자!! (처리 중 뻑나면 std::exception()이 발생할 것이다!!)
*(int*)0 = 10;
}
catch(…)
{
printf(“뻑났음!”);
}
}
3. 그럼 C++ Exception이 여기서 튀어나온다!!
4. 당연히 C++ Exception은 여기에서 잡힌다!
CGCII
예외처리
CGCII 예외 시스템
Cho sanghyun’s Game Classes II
SEH와 C++ Exception이 결합한다면?
IOCP Executor의 처리를 try-catch문으로 처리한다.
void CExecutorIOCP::Execute(DWORD p_tickWait)
{
// 쓰레드마다 설정해 주어야 한다.
_set_se_translator(&fSEHTranslator);
while(m_bDone)
{
DWORD
DWORD
ULONG_PTR
LPOVERLAPPED
dwResult;
dwBytes;
pHKey;
pOverlapped;
try-catch 블록으로 감싼다.
dwResult = GetQueuedCompletionStatus(m_hCP, &dwBytes, &pHKey, &pOverlapped, p_tickWait);
ICGExecutable*
pExecuable
= static_cast<ICGExecutable*>(pOverlapped);
try
{
pExecutable->ProcessExecute(dwResult, dwBytes);
}
pExecutable->ProcessExecute(dwResult,
dwBytes);
catch(…)
만약, 이 함수 실행 중 ‘뻑’이 났다면…
{
}
pExecutable->Release();
}
이 ProcessExecute()함수가 Strong Exception Guarantee를 제
공하는 함수라면…
}
참고) 성능을 위해 while문에 try-catch문은 최대한 빼도록 구현함. try-catch문을 밖으로 빼고 이중 while문을 쓰는 것이 일반적임.
CGCII
예외처리
CGCII 예외 시스템
Cho sanghyun’s Game Classes II
쉽게 말해서 아래와 같이 동작한다.
1.
2.
3.
예외발생 정보 저장.
Mini Dump 남김.
예외 알림.
CGCII의 모든 Engine 시스템의 실행 처리는 CGCII의 Execute System하에서
동작을 하며 완벽한 Strong Exception Guarantee를 보장한다.
CGCII
예외처리
CGCII 예외 처리
Cho sanghyun’s Game Classes II
Pairing처리를 해주어야 하는 것!!들
예를 들어 접속 처리 과정에서 OnConnect()가 정상적으로 호출되었다면 반드시
OnDisconnect()가 호출되어야 한다.
OnEnter() 함수가 호출되었으면 반드시 OnLeave()함수가 호출되어야 한다.
객체에 예외처리 전달
- Message의 처리 과정에서 Message처리 도중 전달되는 객체에도 예외처리 권한이
주어져야 한다.
기타 등등…
원하는 시기에 원하는 대상에 원하는 내용의 예외를 처리할 수 있는 구조를 지원해주어야 한
다.
CGCII
예외처리
강제 예외 발생
Cho sanghyun’s Game Classes II
강제 예외 발생(Force Rasing Exception)이란 강제로 예외를 발생 시키는 것.
‘데드락’이나 ‘무한루프’에 빠진 쓰레드에 강제로 예외를 발생시켜 해결할 수 있다.
다만! 예외 안전이 처리되었을 때만 제대로 처리 가능하다. 그렇지 않다면 예외 발생시켜봐
야 어차피 엉망진창된다.
Managed C++에는 이런 기능 있지만 Native C++에서는 직접 만들어야 된다.
강제 예외 발생 구현은 시간 및 공간 제한 상 생략~
CGCII
예외처리
질문?
Cho sanghyun’s Game Classes II
질문?
[email protected]