failed assertions leave code running behind the message box?

Is there a way to get other threads and timer callbacks to halt while the assertion message box is on the screen We don't want the program state to change between when the assertion happens and when we click Retry to break the debugger.

Answer this question

failed assertions leave code running behind the message box?

  • Novice KT

    There are two kinds of timers: message based timers (WM_TIMER), and timer callbacks (TimerProc).  If it's a message, it needs to be pumped by the thread receiving the message, and since the thread is at the point of the assert, you are not in danger of getting the message (you can't be in two code locations in your thread at the same time).  Timer callbacks should follow the same constraint--they occur in the same thread as the one intended to receive the callback, which you've already suspended.

     


  • mika

    We just did this (DEBUG only)

    #define assert(f) (void) ((f) || (OutputDebugString("Failed Assert: "#f), \
       
    OutputDebugString("\n"), AfxDebugBreak(), 0))
    #define ASSERT(f) assert(f)


  • Olafo

    You haven't specified whether you've created threads with a Win32 API or in .NET. If it's Win32, then you might want to create your own assertion macro that wraps the normal assert plus call a function of your own called SuspendAllThreads(). Assuming you've kept a list of thread handles, you can call the Win32 API SuspendThread on each of them.

    See http://msdn.microsoft.com/library/default.asp url=/library/en-us/dllproc/base/suspendthread.asp

    For timers, perhaps KillTimer

    You can consult with MSDN for further information. Usually I discover Win32 APIs by searching on something I know, like CreateThread, and spidering from there.

    Brian


  • Malcolm Walker

    Your version of ASSERT looks like it is from an earlier version of MFC.  In MFC 8.0 (VS 2005), I might go about it by redefining the ASSERT macro.  I copied the existing MFC definition and added the code in red:

    In stdafx.h:
    extern bool SuspendThreadsOnAssert();

    #undef ASSERT
    #define ASSERT(f) DEBUG_ONLY((void) ((f) || !::SuspendThreadsOnAssert() || !::AfxAssertFailedLine(THIS_FILE, __LINE__) || (AfxDebugBreak(), 0)))

    In stdafx.cpp:
    bool SuspendThreadsOnAssert()
    {
       // suspend your threads and timers if necessary.  Note that this will require globally-scoping your handles.
      
    return true; // continue with assertion
    }

     


  • bounty

    Actually, what's happening is timers set with SetTimer are getting messages because the AfxMessageBox pumps messages in the background. We're not creating extra threads other than the ones MFC creates in the background. We can't call KillTimer because there are various slow timers in lots of different objects.
  • failed assertions leave code running behind the message box?