Windows CRT和断言报告(中止,重试,忽略)

时间:2009-07-13 19:55:21

标签: visual-studio visual-studio-2008 visual-c++

如果应用程序遇到assert(false),则调试模式下的Windows CRT将显示“中止,重试,忽略”窗口,有时会多次创建并填满我的屏幕。< / p>

如果断言会在调试器中断开而不问我任何问题,我会很高兴。

我修改了CRT reporting flags没有效果的内容。

我还尝试修改reporting hook。它会在出现25-30“Abort”对话框后被调用。

我正在构建一个由单独的程序加载的DLL,如果这有帮助的话。它看起来像加载我的DLL的主机程序与调用我的代码的线程不一致。 似乎其中一个线程已停止,但其他线程仍在运行。

如何配置CRT来执行此操作?

5 个答案:

答案 0 :(得分:6)

这适用于(至少对我而言,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;
}

希望有所帮助!

答案 1 :(得分:3)

廖的回答大部分时间都在那里,但我想建议你在调试钩子上添加一个东西:

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

否则你的断言就会消失,进程将终止。

这种方法的问题在于 - 至少对于我家安装的VC Express - 调试器会抛出一个大的“program.exe触发断点”消息而不是正常的断言失败,所以它可能不是一个很大的进步。

答案 2 :(得分:1)

我不确定您是否希望该行为适用于任何assert,或者您是否只是尝试将assert(false)专门用作通用模式以无条件地进入调试器给定的一行。如果是前者,请参阅廖和金的回答。如果是后者,那么你应该真正使用__debugbreak内在函数。

答案 3 :(得分:0)

为什么断言?断言(false)看起来像“应该永远不会发生”的代码在CRT中执行。如果我是你,我会害怕的。总是在一条线上吗?周围有什么评论吗?

编辑: 我的意思是:断言发生在CRT代码中,因为有一些假设是检查你不满足(也许你设法链接到混合运行时,或者你进行托管C ++程序集并忘记手动初始化CRT,或者你试图调用DllMain中的LoadLibrary,或者其他一些不应该发生的事情。)

因此,在弄清楚如何抑制断言之前,先找出它为什么要断言。否则,您可能会在以后遇到看似无关的问题,并且尝试调试它们会有很多乐趣。 (根据你的问题,目前还不清楚你是否知道这些主张是什么)

像这样的代码

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

字面意思是“永远不应该执行这个代码分支”。

答案 4 :(得分: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。