2009-07-13 79 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。