2013-06-28 1 views
0

는, 디버그 빌드가 멀티 스레드 디버그 프로그램 충돌 :CRT 매개 변수 검증 VS2012에서 예상대로 다음 코드는 작동

#include <SDKDDKVer.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <Windows.h> 
#include <io.h> 
#include <assert.h> 

DWORD WINAPI childThread(LPVOID param) { 
    printf("I'm the child!\n"); fflush(stdout); 
    _isatty(-1); 
    //assert(1==0); 
    return 0; 
} 

void myInvalidParameterHandler(const wchar_t * expression, const wchar_t * function, const  wchar_t * file, unsigned int line, uintptr_t pReserved) { 
    wprintf(L"%s:%i %s() - Invalid parameter [%s]", file, line, function, expression); 
} 

int _tmain(int argc, _TCHAR* argv[]) { 
    wprintf(L"Registering invalid parameter handler\n"); 
    _invalid_parameter_handler newHandler = myInvalidParameterHandler; 
    _set_invalid_parameter_handler(newHandler); 

    printf("Testing.\n"); 
    CreateThread(NULL, 0, childThread, NULL, 0, NULL); 
    // CreateThread(NULL, 0, childThread, NULL, 0, NULL); 
    printf("Thread(s) created, press Enter to exit.\n"); 
    getchar(); 
    return 0; 
} 

매개 변수 유효성 검사가 "취소/다시 시도/무시"를 childThread의 _isatty(-1)에서 팝업 원인이됩니다에게 그리고 주변 숙박 필요한만큼. "무시"를 누르면 myInvalidParameterHandler가 호출되고 Enter 키를 누를 때까지 프로그램이 실행됩니다. 문제 없다. 두 번째 CreateThread 이렇게 두 개의 매개 변수 유효성 검사 오류가 한 번 발생 주석의 경우


, 다음 프로그램은 자동으로 종료됩니다. 가끔 Abort/Retry/Ignore가 튀어 나오지만 잠시 후에 사라집니다. 이 프로그램은 메인의 getchar에 대해 결코 멈추지 않습니다.

msvcr110d.dll!_CrtDbgBreak() Line 87 C 
msvcr110d.dll!_VCrtDbgReportW(int nRptType, void * returnAddress, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist) Line 506 C 
msvcr110d.dll!_CrtDbgReportWV(int nRptType, void * returnAddress, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist) Line 262 C++ 
msvcr110d.dll!_CrtDbgReportW(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, ...) Line 279 C++ 
msvcr110d.dll!_isatty(int fh) Line 41 C 
assertTest.exe!childThread(void * param) Line 10 C++ 

이 동시 주장의 일반적인 문제가되지 않습니다 :

디버거 내에서 실행

, 그것은에 중단 점을 안타. 만약 내가 _isatty(-1)assert(1==0)의 코멘트를 교환한다면, 나는 그것이 기대하는 바를 수행한다. 우리는 2 개의 abort/retry/ignore 팝업을 얻었고, 주변에 놀고, 메인 쓰레드는 완료까지 실행됩니다.

릴리스 빌드에이 문제가 없으면 두 스레드에 대해 잘못된 매개 변수 처리기가 호출되고 실행이 항상 계속됩니다.


문맥을 위해, 우리는 종료 자동으로 여러 스레드에서 _isatty(-1) 타격되었다 장기 실행 서버 프로세스를했다. 수정 한 문제이지만이 동작으로 인해 추적하기가 매우 어려웠습니다. 도움이 될만한 것이 있는지 궁금합니다.

나는 question with similar behavior을 보았지만 MinGW &은 컴파일러 버그로 판명되었습니다. VS2012에서 테스트가 작동하는지 확인했습니다.

+0

당신은 이것을 매우 근본적으로 잘못하고 있습니다. C++ 프로그래머는 정의되지 않은 동작을 호출하고 그 결과를 처리 할 권리가 있다고 주장합니다. 이것은 잘 밝혀지지 않았고, 정의되지 않은 행동은 악성 코드에 대한 매우 매력적인 공격 벡터입니다. CRT 공급 업체는 상관하지 않을 것입니다. _invalid_parameter_handler가 프로그램을 종료하거나 예외를 throw하기 위해 ** 예정 **되었습니다. 너는 그렇게하지 않는다. 다음에 일어나는 일은, 음, * 정의되지 않은 *입니다. –

+0

나는 진짜 코드에 대해 당신과 동의한다. 이것은 단지 개념의 증명 (또는 문제의 증거, 오히려)입니다. 잘못된 매개 변수 처리기가 종료되거나 중단되지 않는 유일한 이유는 제어가 처리되기 전에 종료 된 상황과 동작을 대조하는 것입니다. 잘못된 매개 변수가 발생하면 실행을 계속할 수 없습니다. 나는 DebugBreak를 버블 링하기를 원하며 그것에 관한 팝업을 원한다. 이제는 내 컴퓨터가 고정되어 (내 대답에 설명 된대로) 실행이 중지되고 조사가 진행됩니다. –

답변

1

어떻게 든 나 레지스트리에서 디버깅을 사용하지 않도록 설정했습니다. 키 AutoHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug에 누락되었습니다. 1으로 설정하면 Debugger 키에 vsjitdebugger라는 디버거가 호출되었습니다. 아무것도 더 이상 사라지지 않습니다!

왓슨을 사용 중지하려면 http://support.microsoft.com/kb/188296에서 아이디어를 얻었습니다.

+0

semi-related : Cygwin에서 프로그램을 실행할 때 나는 여전히 디버그 팝업을 얻지 못했지만 cmd에서 실행할 때 수행했습니다. 이 문제가 해결되었습니다 : http : // superuser.com/questions/197397/no-crash-dialog-when-a-program-crashes-on-cygwin-on-windows-7 –

관련 문제