본문 바로가기
컴퓨터/디버깅

Debug Assertion Failed!

by adnoctum 2010. 4. 19.
   이 메세지는 디버그 모드로 실행시켰을 때 ASSERT 구문이 실패했을 때 발생하는 메세지로, MS 측에서 가정한 조건을 만족시키지 못하는 것이 있기 때문에 더이상 작업을 진행할 수 없는 경우에 발생하곤 한다. ASSERT 구문은 디버그 모드에서만 동작하고 Release 모드에서는 사라진다. ASSERT 구문은 인자로 주어진 식이 참이면 그냥 지나가고, 참이 아니면 진행을 중단하고 디버깅 상태로 전환된다. 즉,

ASSERT( buf != NULL );

이라는 구문은 buf 가 NULL 이면 디버깅 상태로 전환되고, buf 가 NULL 이 아니면 다음 단계로 진행한다. ASSERT는

#ifdef _DEBUG
...??
#else
ASSERT((EXPR))
#endif

과 같이 구현되어 있어 _DEBUG 가 선언되어 있지 않으면 ASSERT((expr)) 구문을 preprocessor 가 없애버린다. 반면 _DEBUG가 선언되어 있으면 __asm{ int 3 }; 과 비슷한 방법으로 프로그램의 진행을 중단시키는 어떤 루틴이 들어가 있을 것이다. _DEBUG는 프로그램을 디버그 모드로 실행시킬 때 선언되어 있는 것으로, Project option 에서 볼 수 있다. 또한 에러가 났을 때 ASSERT 의 어떤 조건이 만족되지 않아 실패했는지를 살펴 보면 쉽게 디버깅을 할 수 있다.



 
   이 메세지가 발생할 수 있는 경우 중에는 CWnd 를 상속받은 컨트롤의 경우 생성되지 않은 상태에서 어떠한 동작을 취하려 하는 경우로, 이 경우 이 에러 메세지를 무시할 수 있지만 깔끔한 코드는 아니다. 이 에러는 CWnd 에 대한 이해(링크: CWnd에 대하여)가 먼저 필요한데, CWnd가 추상화시키는 HWND type의 m_hWnd 가 아직 제대로 만들어진 윈도우 객체가 아님에도 불구하고 CWnd::ShowWindow 등의 멤버 함수로 그 개체를 조작하려 할 때 발생할 수 있다. 예를 들면 다음과 같은 경우,



위의 코드에서 보는 바와 같이 CComboBox의 instance인 [_cmbMapType]의 변수가 아직 Create를 제대로 거치지 않은 상태에서는 hWnd가 NULL 이고, 이런 상황에서 이 개체에 ResetContent 와 같은 동작을 하면 에러가 날 수밖에 없다. 이것은 주로 dialog 위에 올려 놓은 control의 경우, dialog 가 아직 만들어지지 않은 상태에서 그 변수를 접근하려 할 때 발생하는데, dialog 에 올려 놓은 컨트롤들은 dialog가 만들어 진 후에 생성되기 때문에 dialog 가 만들어지기 전에는 접근할 수 없기 때문이다. 혹은 CView에서 상속받는 등의 경우 OnInitialUpdate 와 같은 구문에 자식 컨트롤을 생성하는 루틴을 집어 넣을 경우, 초기에 OnInitialUpdate는 몇 번의 절차를 거쳐 호출이 되고, 가장 처음 호출이 될 때 아직 자식 control 을 생성할 수 없기 때문에 위와 같은 에러 메세지가 나올 수도 있다. 이와 같은 경우에는 CWnd 의 멤버 함수를 적용할 윈도우가 제대로 만들어진 윈도우인지 확인 후에 동작하면 될 것이다, 다음처럼.

if(::IsWindow(_cmbMapType.GetSafeHwnd()) == static_cast<BOOL>(true)){

    _cmbMapType.ResetContent();

    _cmbMapType.AddString(_T("Perfusion Map"));

    _cmbMapType.AddString(_T("Tmax Map"));

    _cmbMapType.SetCurSel(0);

    _cmbMapType.SetWindowPos(NULL, 0, 0, 100, 200, SWP_NOMOVE | SWP_SHOWWINDOW | SWP_NOZORDER);

}