2012-05-21 4 views
2

임베디드 Windows XP 상자에서 실행되는 DX9 응용 프로그램이 있습니다. 침적 테스트를 위해 하룻밤 사이에 자동으로 그대로두면 약 6 시간에서 8 시간이 지나면 충돌이 발생합니다. 우리의 개발자. 기계 (승리 7) 우리는이 문제를 재현 할 수 없습니다. 나는 또한 그것이 메모리 누출이 아니라고 꽤 확신한다.C++ : __try ... __ except; 해제 모드에서 크래시를 숨 깁니다.

  • 임베디드 시스템에서 디버그에서 동일한 응용 프로그램을 실행하면 충돌이 발생하지 않습니다.
  • 임베디드 시스템에서 메인 루프 업데이트 주위에 __try/__except을 배치하면 충돌이 발생하지 않습니다.

디버그에서 로컬 배열 액세스를 "숨기고있는"일부 추가 바이트 패딩이 있거나 범위 밖의 로컬 배열 액세스가 숨겨져 있거나 일종의 초기화되지 않은 변수가 들여다보고 있습니다. 릴리스에서 실행되는 경우에도,

  1. 디버깅과 유사한 행동 __try/__except 않습니다

    그래서 나는이 개 질문이?

  2. 릴리스 모드에서 크래시가 있지만 디버그 모드가 아닌 경우 어떤 종류의 코드를 스캔해야합니까?
+1

* "릴리스 모드에서 크래시가 있지만 디버그 모드가 아닌 경우 어떤 종류의 코드를 스캔해야합니까?"- 그 코드는 'assert()'또는 사이드 바코드가있는 다른 디버그 코드입니다. effects – Flexo

+1

처음에는 try/except가 없으므로 try/catch가 있습니다. 둘째, 디버그에서 크래시를 관찰하지 않는 많은 이유가있을 수 있습니다. 그 중 하나는 더 오래 실행해야 할 수도 있습니다. –

+0

당신은 try/catch 권리를 의미합니까? – David

답변

3

__try{ } __except()을 사용하는 경우에는 안됩니다.
이들과 C++ 코드는 잘 섞이지 않습니다. (예를 들어, 당신은 그것을 __except()

모두 try.. catch__try .. __except없이 행동으로 기본적으로 동일하지 않습니다)는 줄임표 (catch(...)를 사용하는 경우 C++ try {} catch() {}를 사용해야합니다. 그 래핑 된 함수의 스택에 C++ 객체를 가질 수 없습니다 디버그 및 릴리스 같은

당신이 당신의 문제는 당신이에 대한 모든의를 읽어야 예기치 않은 예외가 의심되는 경우 다음 :. 처음 두 중 하나를 사용

SetUnhandledExceptionFilter() 
_set_se_translator() 

_CrtSetReportMode() 
_RTC_SetErrorFunc() 
_set_abort_behavior() 
_set_error_mode() 
_set_new_handler() 
_set_new_mode() 
_set_purecall_handler() 
set_terminate() 
set_unexpected() 
_set_invalid_parameter_handler() 
_controlfp() 

은 아마 당신이 찾아 낼 수있는 것입니다 당신의 문제가있다. y 빠르게. 나머지는 프로세스에서 가능한 모든 오류 케이스에 대한 절대적인 제어가 필요한 경우에 있습니다.

특히 SetUnhandledExceptionFilter()을 사용하면 예외를 유발 한 코드의 주소를 기록하는 함수 필터를 설정할 수 있습니다. 그런 다음 디버거를 사용하여 해당 코드를 가리킬 수 있습니다. DbgHelp 라이브러리를 사용하고 필터 함수에 제공된 정보를 사용하면 심볼 및 행 번호를 포함하여 충돌의 전체 스택 추적을 인쇄하는 코드를 작성할 수 있습니다.

릴리스 빌드에 대한 디버그 기호를 방출하도록 빌드 구성을 설정했는지 확인하십시오. 우리는 임베디드 시스템에 메인 루프 업데이트 주위에 __try/__except을 배치 할 경우 그들은 단지 도움이 될 수 있습니다 및 응용 프로그램을 늦추기 위해 아무것도하지 않는다 (그러나 어쩌면 더 큰 만들기)

+0

SEH 예외를 잡아내는 IIRC'catch (...) '는 최신 VC++의 일부 최신 버전에서 기본적으로 비활성화되었습니다 (예 : comments [here] (http://stackoverflow.com/questions/1373686/unable-to-catch- c-exception-using-catch)). –

+0

@Matteo :/EHs 대'/ EHa'에 따라 다릅니다. 그러나'_set_se_translator()'를 사용하면 도움이 될 것입니다. –

0

를, 그것은 충돌하지 않습니다.

그럼요.

전체 프로그램 (각 작업자 스레드의 진입 점은 물론) 주위에 단일 __try 블록을 사용하는 것이 좋습니다.이 방법을 사용하면 종료 전에 크래시 덤프를 작성하고 오류 보고서를 작성할 수 있습니다.SEH로 수행 할 수있는 복구 작업은 많지 않습니다. 예외가 여러 가지 오류를 유용하게 구분하기에 충분한 정보를 가지고 있지 않기 때문입니다. 전체 프로그램 상태를 저장하고 디버거로 가져 오는 것은 매우 유용합니다.

참고 : 일부 비디오 드라이버는 catch하는 SEH 예외를 발생 시키므로 일부 논리에서는 설치된 __try 블록에 둘 이상의 SEH 범위가 설치되어있을 것으로 예상합니다.

+0

가드 페이지 등에서 사용되는 SEH 예외를 차단하지 않도록주의해야합니다 (예 : [여기] (http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx)). 나는'SetUnhandledExceptionFilter' 솔루션이 이러한 불편 함을 나타내지는 않을 것이라고 생각한다. (그러나 나는 잘 모르겠다. 나는 잊을지도 모를 세부 사항이 많기 때문에 SEH를 가지고 노는 것을 더 좋아한다.) –

+0

@Matteo : 사용자 예외 필터 검사를 시작하기 전에 OS 예외 처리 코드로 트래핑해야합니다. 실제 스택 오버 플로우 (OS가 스택을 확대하려고 시도했지만 실패한 경우)의 경우에만 액세스 위반을 야기하는 가드 페이지에 대해 걱정할 필요가 있습니다. –

+0

정말입니까? 레이몬드 첸 (Raymond Chen)의 기사에서 알 수있는 한, 가드 페이지 예외가 스택 전체를 가로 지르고 OS 코드가 스택의 상단에서 잡히지 않는 것으로 선언되기 전에 예외를 잡을 것으로 예상됩니다. 따라서, 처리되지 않은 예외 필터는 최상위 레벨 (그러나 여전히 스택의 실제 최상위 레벨이 아님) 인'__try'가 문제를 일으킬 수 있습니다. –