Friday, May 09, 2008

ATL ASSERT on exit

If you tried the sample code I posted yesterday, you might have seen an elusive ATLASSERT dialog box (in Debug mode, of course). When the assertion fires, it happens when the application is closing and the dialog box is very briefly displayed and then closes. You never get to see what caused the assertion in the first place nor do you get a chance to break into the debugger.

To handle this situation, I changed the ATLASSERT macro definition the following way:

extern void AssertBreakpoint();
#define ATLASSERT(expr) { if(!(expr)) AssertBreakpoint(); \

_ASSERTE(expr); }

When the assertion is triggered, the code first calls the AssertBreakpoint function that is there just for you to place a debugger breakpoint. I implemented it with the following rocket-science code:

void AssertBreakpoint() { int a = 3; }

Now you can run the application and you will be sure that you know where the assertion fired. Why? When the debugger stops on your breakpoint you can immediately check the stack and look at the offending code. In my case the assertion was being fired in the CSlideFormView::PreTranslateMessage method. The form view HWND was already destroyed when the

return CWindow::IsDialogMessage(pMsg);

line was executed and this function validates m_hWnd in debug mode.

So if you find yourself in such a situation, use this technique because by defining your own version of ATLASSERT you essentially "infect" all the ATL and WTL code with your custom implementation. All your ATLASSERT are belong to me.

No comments: