以下代码在 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 的“Abort/Retry/Ignore”弹出窗口_isatty(-1)
,它会根据需要一直存在。如果我点击“Ignore”,则调用 myInvalidParameterHandler,程序运行直到我点击 Enter。都好。
如果第二个CreateThread
未注释,因此同时发生两个参数验证失败,则程序静默退出。有时会弹出 Abort/Retry/Ignore,但它会在一秒钟内消失。该程序永远不会挂在 main 的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++
这不是同时断言的一般问题。如果我交换对 and 的评论_isatty(-1)
,assert(1==0)
那么它会达到我的预期。我们得到了两个 abort/retry/ignore 弹出窗口,它们一直在徘徊,主线程运行完成。
发布版本没有这个问题,无效的参数处理程序被两个线程调用并且执行总是继续。
对于上下文,我们有一个长时间运行的服务器进程,它_isatty(-1)
在多个线程中运行并静默退出。这是一个我们已经解决的问题,但这种行为使追踪变得非常困难。我想知道是否有什么可以帮助的。
我看到了一个具有类似行为的问题,但那是 MinGW & 被确定为编译器错误。我已经验证了测试在 VS2012 中有效。