VS2008上的“Debug Assertion”运行时错误?

时间:2010-05-07 02:55:30

标签: c++ visual-studio-2008 mfc debugging

我正在VS2008上编写一个C ++ MFC程序,当我第一次运行程序有时时,我得到了这个“Debug Assertion Error”。当我尝试调试它时,它需要我这个winhand.cpp文件,这不是我写的程序的一部分,所以我不知道如何调试它。

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

那么为什么会发生这种错误呢?为什么它有时只发生(50%的时间)?我该如何调试呢?

如果需要,我会提供一些代码。

谢谢!

7 个答案:

答案 0 :(得分:3)

断言的代码是MFC的CHandleMap类的一部分。 MFC将窗口作为CWnd个对象处理,但Windows将它们作为HWND句柄处理。句柄映射允许MFC将HWND“转换”为指向表示该对象的MFC对象的指针。

断言似乎正在做的是检查当句柄的查找找到MFC对象时,MFC对象也认为它正在包装相同的句柄。

如果它们不同,那么你会得到断言。

所以看起来有些东西正在破坏句柄映射或该句柄的MFC对象,或者你正在做一些不正确的事情,导致这两个数据结构不同步。

尝试调试问题可能需要做的一些事情是确定:

  • 在查找中找到了什么MFC对象(这是pObject指向的内容)
  • MFC对象认为它包裹的内容(即句柄ph[0]和/或ph[1] - 我不知道为什么会有2个)
  • 句柄的用途(即h

手柄看起来像手柄值还是看起来像垃圾? pObject是否指向看起来像MFC对象或垃圾的东西?这些事情中的任何一个看起来都相关吗?

这些问题的答案可能指向您接下来需要做的事情(可能在项目上设置一个看起来像是被删除的调试写断点)。

答案 1 :(得分:1)

几天前我得到了同样的断言,经过一些谷歌搜索, 我在这里找到了我的案例的解决方案: http://forums.codeguru.com/showthread.php?216770-What-would-cause-this-assertion

就我而言,改为滥用

CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();

CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);

会解决它。

答案 2 :(得分:0)

请注意沿着这些方向的代码(来自Stroustrup的书中的内存):

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

(在精神上,当然可以是其他命令和表达)。临时对象在评估其封闭的完整表达式后被破坏,或者至少标准允许它们被破坏。这意味着您想要分配给c1的内容可能会,也可能不会分配给可以分配给c1的内存。编译器可能会提醒您这个问题,根据您分配的具体内容和其他情况(我不是编译器编写器)可能会也可能不会出现问题,这也可以解释为什么有时只会收到此错误消息。

所以在你的鞋子里,我会扫描我的代码以获得类似的表达并清理它们。

答案 3 :(得分:0)

当调试器中断时,将调用堆栈抬高到你的代码的第一位(如果有的话 - 希望有!)。理想情况下,它就像在代码中调用库函数错误一样简单,并且库正在使用断言捕获错误并提醒您。 (我认为任何人都无法告诉代码有什么问题,我们需要看你的代码。)

否则,您正在进行一些棘手的调试:您正在对断言的库(看起来像MFC)做错了所以请返回并查看所有MFC代码并确保一切正确并根据文档。

答案 4 :(得分:0)

这看起来很像我今天早上的错误。这是在OnIdle()中发生的吗?

答案 5 :(得分:0)

我知道这是一篇非常古老的帖子,但希望有人可以从我的回答中得到一些帮助。

由于我的错误,我最近也遇到过类似的问题,然后我遇到了这个帖子并得到了" pac"帖子的提示。

我发现如果我使用DeleteDC()来释放从GetWindowDC()或GetDC()返回的DC,一旦CPaintDC对象实例超出范围,我将在MFC框架中得到上述断言。

CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);

您必须仅将DeleteDC()与CreateDC()API结合使用。

CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();

答案 6 :(得分:0)

当我们的某些项目dll将MFC链接为静态库而将某些DLL链接为共享库时,我们遇到了这个问题(请在“项目”设置中选中“使用MFC”)