views:

664

answers:

5

The Windows CRT in debug mode will show a "Abort,Retry, Ignore" window if the application hits an assert(false) and sometimes it is created many times and fills my screen.

I would love it if the assert would break in the debugger and not ask me any questions.

I have modified the CRT reporting flags which have had no effect.

I have also tried to modify the reporting hook. It does get called by after 25-30 "Abort" dialogs appear.

I am building a DLL that is loaded by a separate program if that helps. It also looks like the host program loading my DLL is not consistent with what thread is calling my code. It seems like the one of the threads was stopped but the others are still running.

How do I configure the CRT to do this ?

+3  A: 

This works (for me atleast, on vs 2008): (Essentially, return TRUE from the hooked function)

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;
}

You could also write your own assert-like behavior (Note that this will show the "Break, Continue" dialog):

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

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

Hope that helps!

Liao
Unfortunately this does not solve my problem.I get about 25-30 Abort,Retry,Ignore dialogs before the CrtDbgHook is called.
witkamp
A: 

Why does it assert? assert(false) looks like "should never happen" code was executed in CRT. I would be scared if I were you. Is it always on one line? Are there any comments around it?

EDIT: I mean: assert happens in CRT code because there is some assumption it is checking that you don't meet (maybe you managed to link to mixed runtime, or you making managed C++ assembly and forgot to manually initialize CRT, or you trying to call LoadLibrary from within DllMain, or some other thing that should never happen).

So before figuring out how to suppress asserts, find out why exactly does it assert in the first place. Otherwise you'll likely get seemengly unrelated problems later on and will have lots of fun trying to debug them. (from your question it is unclear if you know what those asserts are about)

Code like this

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

literally means "this branch of code should never be executed".

Eugene
do you mean why assert(false) asserts ? its because when you assert, the condition should evaluate to true to be "ok", the thinking being "assert that a+b=4", so if a+b is not equal to 4, the "assertion has failed".
Liao
sorry, i dint understand your last 2 questions - is what always on one line ? any comments "around" it - what do you mean?
Liao
You are absolutely right in that one should first figure out why an assert is occurring. And using assert(false); is certainly one way to ensure that "this branch of code should never be executed". +1 for adding more info/correct practice to this, that i neglected to do.
Liao
+1  A: 

Liao's answer takes you most of the way there, but I'd like to propose that you add one more thing to your debug hook:

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

Otherwise your assertions will just disappear and the process will terminate.

Problem with this approach is that -- at least for my home install of VC Express -- the debugger throws up a big "program.exe has triggered a breakpoint" message instead of the normal Assertion Failure, so it may not be a great improvement.

Kim Gräsman
+1  A: 

I'm not sure if you want the behavior to be for any assert, or whether you're just trying to use assert(false) specifically as a general-purpose pattern to unconditionally break into debugger on a given line. If it's the former, see Liao's and Kim's answers. If it's the latter, then you should really use the __debugbreak intrinsic function instead.

Pavel Minaev
A: 

Why not use DebugBreak Function?

Or even use an opcode?

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

Before Visual C++ 2005, the instruction,

__asm int 3 did not cause native code to be generated when compiled with /clr; the compiler translated the instruction to a CLR break instruction. Beginning in Visual C++ 2005, __asm int 3 now results in native code generation for the function. If you want a function to cause a break point in your code and if you want that function compiled to MSIL, use __debugbreak.

zproxy
I don't want to change the definition of the assert macro.This is not just for my code but also for static libraries that I link against which also use the assert macro
witkamp
I did not suggest the change, this is the microsoft's header file...
zproxy