블로그는 나의 힘!
[ Programing ]/C++2015. 10. 15. 15:17

C++ STL Iterator 오류시 MiniDump 남지 않는 현상. (특히 릴리즈 모드)


해결법

 


C++ 11 인 경우 최상단에 define 재 선언 하여 준다.

#undef _ITERATOR_DEBUG_LEVEL
#define _ITERATOR_DEBUG_LEVEL   0


( 그외 이전 버전은 _SECURE_SCL, _SECURE_SCL_THROW, _HSA_ITERATOR_DEBUGGING 매크로 참조 )

 

 

 

 

C++ 98 인 경우 (2010 이전 구버전) 함수를 재 정의 한다.

 

#include <stdlib.h>
#include <crtdbg.h>

 

int _custom_report_hook( int reportType, char* message, int* returnValue )
{

 

      //UNREFERENCED_PARAMETER( message );
      //UNREFERENCED_PARAMETER( returnValue );

      //if( NULL != message )
           //printf( "In_ReportHook = %s \n", message );

 

      if( _CRT_WARN != reportType )
      {
            // 크래시 유발
            *(int*)0 = 0;

            return false;
      }

     

     return true;
}

 

// expression : C런타임 함수에서 발생한 예외 설명 문자열.
// function : 함수 명
// file : 소스 파일 명
// line : 에러 발생한 코드 행 번호
// pReserved : 예약어
void _custom_invalid_parameter_handler( const wchar_t* expression,

                                                      const wchar_t* function,

                                                      const wchar_t* file,

                                                      unsigned int line,

                                                      uintptr_t pReserved )
{

      //UNREFERENCED_PARAMETER( expression );
      //UNREFERENCED_PARAMETER( func );
      //UNREFERENCED_PARAMETER( file );
      //UNREFERENCED_PARAMETER( line );
      //UNREFERENCED_PARAMETER( pReserved );

      //printf( "Invalid Parameter Handler. \n" );

      // 크래쉬 유발
      //*(int*)0 = 0;

      printf( "EXCEPTION CATCH [%s][%s][%s][%d] \n", expression, func, file, line );
}

 

void SetSTLCustomHandler()

{

      // 메모리 정보 후킹 (외 메모리 관련 쪽 예외 정의)
      _CrtSetReportHook( &_custom_report_hook );

 

      // 핸들러 선언
      _invalid_parameter_handler oldHandler, reportHandler;

 

      // 정의한 함수를 선언하기 위한 (가상 함수) 핸들러 등록
      reportHandler = _custom_invalid_parameter_handler;

 

      // 선언한 함수 핸들러 등록
      oldHandler = _set_invalid_parameter_handler( reportHandler );

 

      // C런타임 Assert 팝업 상자 비활성
      _CrtSetReportMode( _CRT_ASSERT, 0 );

}

 

//////////////////////////////////////////////////

 

void TestFunction()

{

      std::vector<int> vecTestArray;

      vecTestArray.push_back( 1 );

      vecTestArray.push_back( 2 );

      vecTestArray.push_back( 3 );

 

      for( std::vector<int>::iterator iterTest = vecTestArray.begin(); iterTest != vecTestArray.end(); ++iterTest )

      {     // 테스트(릴리즈 모드) 위해 강제적 오류 발생

            vecTestArray.erase( iterTest );

      }

}

 

void main()
{
      SetSTLCustomHandler();

 

      // Test

      TestFunction();
}

 

 

 

정리


STL의 vector(예를 들어 링크 리스트 중)를 따라 올라가 보면 릴리즈 모드 시 _HAS_ITERATOR_DEBUGGING 의

기본 설정(활성화)에 따라 처리 예외처리를 하는데 _SCL_SECURE_VALIDATE() or _SCL_SECURE_VALIDATE_RANGE()에서

MyPtr(자료)를 체크한다.

 

정의를 따라가 보면 _SCL_SECURE_VALIDATE 안에 _SCL_SECURE_OUT_OF_RANGE_NO_ASSERT가 있으며

_SECURE_SCL_THROWS가 기본 설정(비활성)시 _SCL_SECURE_INVALID_PARAMETER() 정의 되어 있다.

 

릴리즈 모드 설정인 _invalid_parameter_noinfo()로 들어가 초기화 후 _invalid_parameter()에서

위에 정의한 _invalid_parameter_handler 핸들러에 설정된 크래시를 수행해 강제적으로 예외처리를 만든다.

 

만약 핸들러를 설정하지 않았다면 그냥 넘어가 _invoke_watson()에서 TerminateProcess()를 수행하여 STL에서 자체적으로 종료 시켜 예외 처리를 남기지 않는다.

 

그러니 (2010 이전 구버전) 미니덤프를 남길려면 STL에 _invalid_parameter_handler 핸들러 설정을 해 줘야 한다.

 

 

Win32_VS2008.zip

 

 

 

 

 

참조 :
C++ 98 관련

technet.microsoft.com/ko-kr/library/0yysf5e6
blog.daum.net/supremehj/69
blog.naver.com/minkme/120098163759

charlespark.tistory.com/79

 

 

Posted by Mister_Q