如果应用程序遇到assert(false)
,则调试模式下的Windows CRT将显示“中止,重试,忽略”窗口,有时会多次创建并填满我的屏幕。< / p>
如果断言会在调试器中断开而不问我任何问题,我会很高兴。
我修改了CRT reporting flags没有效果的内容。
我还尝试修改reporting hook。它会在出现25-30“Abort”对话框后被调用。
我正在构建一个由单独的程序加载的DLL,如果这有帮助的话。它看起来像加载我的DLL的主机程序与调用我的代码的线程不一致。 似乎其中一个线程已停止,但其他线程仍在运行。
如何配置CRT来执行此操作?
答案 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。