CRT参数验证崩溃了多线程调试程序

时间:2013-06-28 15:11:38

标签: c++ windows multithreading visual-studio

以下代码在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中有效。

1 个答案:

答案 0 :(得分:1)

想出来 - 不知何故,我在我的注册表中禁用了调试功能。 Auto中的密钥HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug丢失了。将其设置为1会导致调用Debugger密钥中命名的调试器vsjitdebugger。没有什么消失了!

http://support.microsoft.com/kb/188296获得关于禁用Watson的想法。