는, 디버그 빌드가 멀티 스레드 디버그 프로그램 충돌 :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에서 테스트가 작동하는지 확인했습니다.
당신은 이것을 매우 근본적으로 잘못하고 있습니다. C++ 프로그래머는 정의되지 않은 동작을 호출하고 그 결과를 처리 할 권리가 있다고 주장합니다. 이것은 잘 밝혀지지 않았고, 정의되지 않은 행동은 악성 코드에 대한 매우 매력적인 공격 벡터입니다. CRT 공급 업체는 상관하지 않을 것입니다. _invalid_parameter_handler가 프로그램을 종료하거나 예외를 throw하기 위해 ** 예정 **되었습니다. 너는 그렇게하지 않는다. 다음에 일어나는 일은, 음, * 정의되지 않은 *입니다. –
나는 진짜 코드에 대해 당신과 동의한다. 이것은 단지 개념의 증명 (또는 문제의 증거, 오히려)입니다. 잘못된 매개 변수 처리기가 종료되거나 중단되지 않는 유일한 이유는 제어가 처리되기 전에 종료 된 상황과 동작을 대조하는 것입니다. 잘못된 매개 변수가 발생하면 실행을 계속할 수 없습니다. 나는 DebugBreak를 버블 링하기를 원하며 그것에 관한 팝업을 원한다. 이제는 내 컴퓨터가 고정되어 (내 대답에 설명 된대로) 실행이 중지되고 조사가 진행됩니다. –