사용자 도구

사이트 도구


kb:structuredexceptionvscppexception

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:structuredexceptionvscppexception [2014/11/07 10:43] (현재)
줄 1: 줄 1:
 +====== Structured Exception vs C++ Exception ======
 +SE(Structured Exception)과 CE(C++ Exception)을 일관된 방법으로 사용하기
 +
 +
 +====== 무엇이 문제인가?​ ======
 +SE를 CE와 혼용해서 사용하기 위해서는 대충 아래와 같은 클래스를 만들어 사용해야한다.
 +<code cpp>
 +#ifndef INCLUDED_SEEXCEPTION_H
 +#define INCLUDED_SEEXCEPTION_H
 +
 +#include <​eh.h>​
 +
 +// Maps a Win32 structured exception to a C++ exception.
 +// Useful to trap things like access violations.
 +class SeException ​
 +{
 +private:
 +    unsigned int m_se;
 +
 +public:
 +    SeException(unsigned int n) : m_se(n) {}
 +    ~SeException() {}
 +
 +public:
 +    unsigned int GetSeNumber() { return m_se; }
 +
 +    // Call this function to start the mapping
 +    static void Init() {
 +        static bool g_Init = false;
 +        if (!g_Init) {
 +            _set_se_translator(Translator);​
 +            g_Init = true;
 +        }
 +    }
 +
 +private:
 +    SeException() {}
 +    SeException( SeException&​ ) {}
 +
 +    static void Translator( unsigned int u, _EXCEPTION_POINTERS* pExp ) {
 +        throw SeException(u);​
 +    }
 +};
 +
 +#endif // INCLUDED_SEEXCEPTION_H
 +</​code>​
 +
 +위 클래스에서 핵심이 되는 것은 [[http://​msdn.microsoft.com/​library/​default.asp?​url=/​library/​en-us/​vclib/​html/​_crt__set_se_translator.asp | _set_se_translator]] 함수다. 이 함수만 제대로 호출하면 try-catch 구문에서 SE를 잡아낼 수 있다.
 +
 +문제가 되는 것은 VisualCpp의 관련 세팅(구성 속성 > C/C++ > C++ 예외 처리 가능)이 기본적으로 동기 예외 처리 모델(Synchronous Exception Model, /​EHs)이라는 점이다. try-catch 구문에서 SE를 잡아내기 위해서는,​ 즉 _set_se_translator 함수를 사용하기 위해서는 비동기 예외 처리 모델(Asynchronous Exception Model, /EHa)을 사용해야한다.
 +
 +  * 비동기 예외 처리 모델 -- 어떤 명령(instruction)이라도 예외를 발생시킬 수 있다.
 +  * 동기 예외 처리 모델 -- throw 구문 안에서만 예외를 발생시킬 수 있다. 그러므로 컴파일러가 좀더 많은 최적화를 수행할 수 있다. 기본 옵션이다.
 +
 +비동기 모델을 사용하지 않을 경우, 스택 언와인드가 일어났을 때, 객체의 소멸자가 호출되지 않을 수 있으며, 예외 자체도 가장 가까운 try-catch 블록에서 잡히지 않을 수 있다. 아래의 최적화 관련 문제에서도 나오지만,​ 이런 문제는 주로 릴리즈 빌드에서 일어나는 모양이다. 최적화하지 않아야할 것을 최적화해버리는 것이니깐.
 +
 +비동기 모델을 사용할 때 또 생각해 봐야할 것은 최적화 관련 문제다. 동기 모델과는 달리, 비동기 모델에서는 컴파일러가 코드의 흐름을 예측할 수 없기 때문에 최적화 기능 중에 많은 것이 빠지게 된다. 프로그램의 성능을 떨어뜨리면서까지 둘 모두를 사용할 필요가 있는가에 대해서 생각해 보라.
 +
 +
 +====== 주의할 점 ======
 +  * 비동기 예외 처리 모델은 콤보 박스를 이용해 선택할 수 없으므로,​ "​구성 속성 > C/C++ > C++ 예외 처리 가능 플래그"​를 "​아니오"​로 바꾸고, "​구성 속성 > C/C++ > 명령줄"​에서 추가 옵션에다 직접 입력해 줘야한다.
 +  * 다중 스레드 환경에서는 스레드를 생성할 때마다 그 스레드 안에서 _set_se_translator 함수를 호출해줘야한다. 예외 형식 변경이 각 스레드별로 관리되기 때문이다.
 +
 +
 +====== 링크 ======
 +  * [[http://​www.codeproject.com/​cpp/​exception.asp | Several classes for exception handling]] \\ C++ wrappers for stack trace, unhandled exception and win32 structured exceptions
 +  * [[http://​www.codeproject.com/​cpp/​seexception.asp | SEH and C++ Exceptions - catch all in one]] \\ This article describes how to handle SE and C++ exception together.
 +  * [[http://​www.gamedev.net/​reference/​articles/​article1372.asp | An Exceptional Quest]]
 +  * [[http://​www.microsoft.com/​msj/​1099/​bugslayer/​bugslayer1099.aspx | MSJ 1999.10 Bugslayer -- When SEH translators don't work.]]
 +  * [[http://​blogs.msdn.com/​larryosterman/​archive/​2004/​09/​10/​228068.aspx | Structured Exception Handling Considered Harmful]]
 +  * [[http://​blogs.msdn.com/​jaredpar/​archive/​2008/​01/​11/​mixing-seh-and-c-exceptions.aspx | Mixing SEH and C++ Exceptions]]
 +
 +----
 +  * see also [[ExceptionHandling]],​ [[SEH]]
  
kb/structuredexceptionvscppexception.txt · 마지막으로 수정됨: 2014/11/07 10:43 (바깥 편집)