以下代码在VS2012,Debug build:
中按预期工作#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)
的评论,那么它会做我期望的事情。我们得到两个中止/重试/忽略弹出窗口,它们会挂起,主线程运行完成。
发布版本没有此问题,将为两个线程调用无效参数处理程序,并始终继续执行。
对于上下文,我们有一个长时间运行的服务器进程,它在多个线程中命中_isatty(-1)
并以静默方式退出。这是我们修复过的问题,但这种行为使得追踪变得非常困难。我想知道是否有什么可以帮助。
我看到question with similar behavior,但那是MinGW&amp;被确定为编译器错误。我已经验证了测试在VS2012中有效。
答案 0 :(得分:1)
想出来 - 不知何故,我在我的注册表中禁用了调试功能。 Auto
中的密钥HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
丢失了。将其设置为1
会导致调用Debugger
密钥中命名的调试器vsjitdebugger。没有什么消失了!
从http://support.microsoft.com/kb/188296获得关于禁用Watson的想法。