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 핸들러 설정을 해 줘야 한다.
참조 :
C++ 98 관련
technet.microsoft.com/ko-kr/library/0yysf5e6
blog.daum.net/supremehj/69
blog.naver.com/minkme/120098163759
'[ Programing ] > C++' 카테고리의 다른 글
디버깅 메모리 중단점. (0) | 2018.04.11 |
---|---|
C++ 데이터 형식 범위 (TYPE SIZE) (0) | 2018.02.28 |
문자열 함수 (멀티바이트->유니코드->TCHAR) (0) | 2014.04.29 |
SYSTEMTIME 시간 차이 Date -> TickTime 계산. mktime, difftime (0) | 2013.12.20 |
std::string 에 sptintf 형태 쉽게 사용하기 (0) | 2013.11.14 |