C ++关于跟踪访问冲突的任何建议?

时间:2012-05-08 03:35:21

标签: c++ class instance destructor access-violation

我在尝试追踪程序中的访问冲突时遇到了问题。它是在第三次调用析构函数时发生的,恰好在析构函数出现完成时。

我花了好几个小时试图追踪这一点,所以我正在寻找有关我能做的事情的进一步建议。我正在使用newdelete运算符创建类实例。 Visual Studio输出窗口显示:

First-chance exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab. Unhandled exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.

我有什么办法可以尝试找出这些内存位置的内容吗?

调用堆栈窗口显示以下内容(与我按照时间顺序粘贴它的顺序相反,最早到最新):

Program.exe!Network::`scalar deleting destructor'()  + 0x2b bytes   C++

Program.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >()  Line 754 + 0xf bytes    C++

Program.exe!std::_String_val<wchar_t,std::allocator<wchar_t> >::~_String_val<wchar_t,std::allocator<wchar_t> >()  Line 478 + 0xb bytes  C++
  

msvcp100d.dll!std :: _ Container_base12 :: _ Orphan_all()第214行+ 0x5字节C ++

我对此信息的最佳猜测是,是否存在导致此问题的某种字符串变量?有没有人对解释这些信息有任何建议?

提前感谢任何其他建议也很有用。

我在Windows 7下编码并使用Visual Studio 2010 Professional。

3 个答案:

答案 0 :(得分:3)

在使用BoundsChecker (now part of Borland DevPartner)之前,我已成功跟踪内存错误。有许多类似的产品也可能有所帮助:HeapAgentRational Purify。这些看起来很像ValGrind,但在Windows上工作。

以下是3个可能有所帮助的开源替代方案:

  1. DUMA(从它的外观来看,你必须自己为Windows构建它,但README包含了一些关于这样做的注释)

  2. XMEM

  3. elephant

  4. 我不知道这些是如何表现的,但它们看起来非常有前景,看起来它们都以某种方式在Windows上运行。

    Microsoft page on managing memory errors也可能有所帮助,并且还包含设置内存断点的链接,这可能有助于您了解数据首次被删除或更改的时间。祝你好运!

答案 1 :(得分:2)

使用Microsoft Heap Debugging的东西,并希望你的是其设计的案例之一。 Purify将是之后的下一步。

它内置于Visual Studio中,在某些情况下很有用。如果它能够正常工作,那肯定会让IBM为Purify提供两到三个装满现金的口袋。

您可以找到信息here

TL; DR 主要是,这样做

int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// Turn On (OR) - Keep freed memory blocks in the
// heap's linked list and mark them as freed
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;

// Turn on memory checking at each heap operation
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;

// Set the new state for the flag
_CrtSetDbgFlag( tmpFlag );

如果_CRTDBG_CHECK_ALWAYS_DF标志运行得太慢,您可以在不同位置切换{{1}}标志。但是,我会检查每个堆操作几次,以便了解问题发生的位置。

答案 2 :(得分:1)

我在这个博客上写了一些提示

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

您需要做的主要事情是在有错误的代码仍在堆栈中时发生崩溃或异常。很多时候,在执行并返回错误的代码之后的一段时间内,您会收到访问冲突,并且实际上可能需要很长时间(在计算机时间内)。在这种情况下,几乎不可能弄明白。

在你的情况下,如果在删除时标记了问题,则表明堆已损坏,这是C ++的两个常见原因是双删除和混合数组删除(当你应该使用delete []时使用delete或反过来说。)

如果你可以用简单的代码重现它,我会找到上面的两个问题。否则,请下载Microsoft调试工具并使用gflags +hpa -i program.exe使堆对腐败更加敏感(它将更快地报告错误)。