2009-07-13 74 views
4

在Windows CRT在調試模式下會顯示出「中止,重試,忽略」如果應用程序擊中assert(false)有時它創造了很多次,填滿了我的窗口屏幕。的Windows CRT和斷言報告(中止,重試,忽略)

如果斷言會在調試器中斷,並不問我任何問題,我會喜歡它。

我修改了CRT reporting flags,這些都沒有效果。我也試過修改reporting hook。它會在25-30「Abort」對話框出現後被調用。

我正在構建一個單獨的程序加載的DLL,如果有幫助的話。它看起來像加載我的DLL的主機程序不符合什麼線程調用我的代碼。 看來,其中一個線程已停止,但其他線程仍在運行。

如何配置CRT來做到這一點?

回答

5

這工作(對我來說ATLEAST,在VS 2008): (從本質上講,從掛鉤函數返回TRUE)

int __cdecl CrtDbgHook(int nReportType, char* szMsg, int* pnRet) 
{ 
    return TRUE;//Return true - Abort,Retry,Ignore dialog will *not* be displayed 
    return FALSE;//Return false - Abort,Retry,Ignore dialog *will be displayed* 
} 
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 
{ 
    _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, CrtDbgHook); 
    assert(false); 
    getch(); 
    return 1; 
} 

你也可以寫你自己的斷言類似的行爲(請注意,這將顯示「Break,Continue」對話框):

#define MYASSERT(x) { if(!(x)) {DbgRaiseAssertionFailure();} } 

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) 
{ 
    MYASSERT(false); 
    getch(); 
    return 1; 
} 

希望對您有所幫助!

+0

不幸的是,這並沒有解決我的問題。 在調用CrtDbgHook之前,我得到了大約25-30中止,重試,忽略對話框。 – Ted 2009-07-23 18:34:58

0

它爲什麼斷言? assert(false)看起來像「永遠不會發生」的代碼在CRT中執行。如果我是你,我會感到害怕。它總是在一條線上?有沒有關於它的評論?

編輯: 我的意思是:斷言發生在CRT的代碼,因爲有一些假設它是檢查不符合你(也許你成功地鏈接到混合運行時,或者你做託管C++組件,忘了手動初始化CRT,或者你試圖從DllMain中調用LoadLibrary,或者其他一些永遠不會發生的事情)。

因此,在弄清楚如何抑制斷言之前,首先找出它究竟爲什麼斷言。否則,你以後可能會看到無關緊要的問題,並嘗試調試它們會有很多樂趣。 (從你的問題,目前還不清楚,如果你知道這些斷言是約)

這樣的代碼

if(somebadcondition) 
{ 
    assert(false); 
    // recovery code 
} 

字面意思是「這個代碼分支應該永遠不會被執行。」

+0

你的意思是爲什麼assert(false)斷言?因爲當你斷言時,條件應該評估爲「真」,思維是「斷言a + b = 4」,所以如果a + b不等於4,那麼「斷言失敗」。 – Liao 2009-07-21 07:01:05

+0

抱歉,我不知道你最近的2個問題 - 總是在一行上? 「圍繞」它的任何評論 - 你是什麼意思? – Liao 2009-07-21 07:02:30

+0

你是絕對正確的,應該首先找出爲什麼斷言正在發生。並使用assert(false);當然是確保「這段代碼永遠不會被執行」的一種方法。爲+1添加更多的信息/正確的做法,這個,我忽略了做。 – Liao 2009-07-22 04:45:05

2

廖的回答把你大部分的方式,但我想建議你加上一句話,就是你的調試鉤:

int __cdecl StraightToDebugger(int, char*, int*) 
{ 
    _CrtDbgBreak(); // breaks into debugger 
    return TRUE; // handled -- don't process further. 
} 

否則你的說法只會消失,該進程將終止。

這種方法的問題是 - 至少對於我的VC Express家庭安裝 - 調試器會拋出一個大的「program.exe觸發了斷點」消息而不是正常的斷言失敗,因此它可能不會是一個很大的改進。

1

我不確定您是否希望該行爲適用於任何assert,或者您是否只是試圖將assert(false)專門用作通用模式,以便在給定行上無條件地插入調試器。如果是前者,請參閱廖的和金的回答。如果是後者,那麼你應該真的使用內部函數來代替。

0

爲什麼不使用DebugBreak Function

甚至使用操作碼?

#ifdef _X86_ 
#define BreakPoint()  _asm { int 3h } 
#else 
#define BreakPoint()  DebugBreak() 
#endif 

Before Visual C++ 2005, the instruction

__asm int 3沒有造成當與 /CLR編譯要產生本地代碼;編譯器將 指令翻譯成CLR中斷 指令。從Visual C++ 2005開始,__asm int 3現在導致 函數的本地代碼生成。如果你想要一個函數 在你的代碼中產生一個斷點,並且如果你想把該函數編譯爲 MSIL,使用__debugbreak。