2013-06-28 21 views
0

下面的代碼將按預期在VS2012,調試版本:CRT參數驗證崩潰多線程調試程序

#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未被註釋於是兩個參數驗證失敗發生在一次,然後該程序退出靜默。有時中止/重試/忽略彈出,但它在一秒鐘內消失。該程序永遠不會掛起主要的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 &被確定爲編譯器bug。我已經證實,測試在VS2012中起作用。

+0

你正在做這個很根本錯誤的。 C++程序員聲稱有權調用未定義的行爲並處理這樣做的後果。這並沒有得到太好的結果,未定義的行爲是一個非常有吸引力的惡意軟件攻擊媒介。您可能不在意,您的CRT供應商會這麼做。你的_invalid_parameter_handler是** expected **來終止程序或拋出異常。你不這樣做。接下來會發生的是,* undefined *。 –

+0

我同意你的真實代碼。這僅僅是一個概念證明(或者證明問題)。無效參數處理程序沒有退出或中斷的唯一原因是將行爲與控制到達之前退出的情況進行對比。 我不想在發生無效參數時繼續執行。我想要一個DebugBreak泡沫,我想要得到一個關於它的彈出窗口。現在我的機器是固定的(如我的回答中所述),它停止執行並讓我調查它。 –

回答

1

想通了 - 不知何故,我在我的註冊表中禁用了調試功能。他們的鑰匙AutoHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug丟失。將其設置爲1會導致調用名爲Debugger的調試器vsjitdebugger。沒有消失了!

http://support.microsoft.com/kb/188296得到關於禁用沃森的想法。

+0

半相關:從Cygwim運行程序時,我仍然沒有收到任何調試彈出窗口,但是我在從cmd運行時執行了此操作。這解決了這個問題:http://超級用戶。COM /問題/ 197397 /無碰撞的對話中,當-A-程序崩潰-ON-cygwin的上窗口-7 –