views:

195

answers:

4

I'm writing a C++ MFC program on VS2008 and I'm getting this "Debug Assertion Error" when I first run the program sometimes. When I try to debug it, it takes me to this winhand.cpp file which is not part of the program I wrote so I'm not sure how to debug this.

It takes the error to this place in winhand.cpp

 CObject* pTemp = LookupTemporary(h);
 if (pTemp != NULL)
 {
  // temporary objects must have correct handle values
  HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset);  // after CObject
  ASSERT(ph[0] == h || ph[0] == NULL);
  if (m_nHandles == 2)
   ASSERT(ph[1] == h);
 }

So why does this error happen? Why does it only happen sometimes (50% of the time)? How would I debug this?

I'll provide some code if is needed.

THANKS!

A: 

Look out for code along those lines (from memory from Stroustrup's book):

c1 = (t2+t3).c_str();

(in spirit, could be other commands and expressions of course).Temporary objects are destroyed after their enclosing full expression has been evaluated, or at least the standard allows them to be. That means that what you would like to allocate to c1 may, or may not, still be in memory where it can be assigned to c1. The compiler may alert you to this issue, and the issue may or may not arise depending on what exactly you assign and other circumstances (I am not compiler writer), which would also explain why you get this error message only sometimes.

So in your shoes, I'd scan my code for similar expressions and clean them up.

gnometorule
A: 

When the debugger breaks, head up the call stack to the first bit of your code (if there is any - hopefully there is!). Ideally it's as simple as something in your code calling a library function incorrectly, and the library is catching the error with an assert and alerting you to that. (I don't think anyone will be able to tell what's wrong from the library code, we need to see your code.)

Otherwise, you're in for some tricky debugging: you're doing something wrong with the library that is asserting (looks like MFC) so go back and review all your MFC code and make sure everything is correct and according to the documentation.

AshleysBrain
A: 

This looks suspiciously like an error I had this morning. Is this happening in OnIdle()?

Roel
+2  A: 

The code that is asserting is part of MFC's CHandleMap class. MFC deals with windows as CWnd objects, but Windows deals with them as HWND handles. the handle map allows MFC to 'convert' an HWND into a pointer to the MFC object representing that object.

What the assertion seems to be doing is checking that when a lookup of the handle finds an MFC object, that the MFC object also thinks it's wrapping the same handle.

If they're different, then you get the assertion.

So it would appear that something is corrupting the handle map or the MFC object for that handle or you're doing something incorrect that gets these 2 data structures out of sync.

Some things you might do to try to debug the problem is to determine:

  • what MFC object is being found in the lookup (that's what's being pointed to by pObject)
  • what the MFC object thinks it's wrapping (that's the handle ph[0] and/or ph[1] - I'm not sure why there can be 2 of them)
  • what the handle is for (that's h)

Do the handles look like handle values or do they look like garbage? Does pObject point to something that looks like an MFC object, or garbage? Do any of these these things seem related?

The answers to these questions may point to what you need to do next (maybe set a debug write breakpoint on the item that looks like it's trashed).

Michael Burr