c++ 未处理的异常 - 如何调试

Posted

技术标签:

【中文标题】c++ 未处理的异常 - 如何调试【英文标题】:c++ Unhandled exception - how to debug 【发布时间】:2013-04-25 15:26:59 【问题描述】:

在调试模式下运行测试用例时遇到问题:我收到一个弹出框,显示消息“Test.exe 中 0x7c812fd3 处的未处理异常:0xE0000003:0xe0000003。”。 free.c 中的代码中断:

void __cdecl _free_base (void * pBlock)

    int retval = 0;

    if (pBlock == NULL)
        return;

    RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));

    retval = HeapFree(_crtheap, 0, pBlock);
    if (retval == 0)
    
        errno = _get_errno_from_oserr(GetLastError());
    

在“retval =...”行,_crtheap = 0x00df0000 和 pBlock = 0x967c93d3。调用堆栈在“kernel32.dll!7c812fd3()”处中断,调用堆栈中的另一个条目更靠下: ">msvcr100d.dll!_free_base(void * pBlock=0x967c93d3) 第 50 行 + 0x13 字节。

我用谷歌搜索了很多,问题可能来自释放内存严重时间。 尽管有这种模糊和混乱的描述,任何人都可以暗示如何定位问题吗?也许如何解决它?

让我有点奇怪的是,在发布模式下运行测试时我没有遇到这种情况......

亲切的问候, 斯文德

【问题讨论】:

调试模式只有错误的通常原因是未初始化的变量。也许您正在释放一个从未被赋予值的指针。 在发布模式下,这些检查没有完成,因此你只能在调试模式下收到通知(问题仍然存在于发布中,你很幸运,它似乎没有导致任何进一步的错误) .向上跟踪堆栈,直到找到您编写的函数,并尝试找出那里出了什么问题(例如,双重释放或释放实际上未分配的地址)。 你能提供更多细节吗?什么类型的对象被释放?例如它是一个智能指针吗 您没有提示您的应用程序,但是使用 RAII(通过 std::vector、std::unique_ptr、std::shared_ptr 等)来管理您的所有资源意味着您将消除几乎所有与释放资源相关的错误。如果您有一个超出数组边界的指针,RAII 不会阻止它,但是像 std::vector 这样的检查容器可以在调试模式下检测到它。我的猜测是它只会在调试 b/c 中失败,它只是在调试模式下检查一些失败条件,或者在发布模式下不会发生损坏,因为代码/数据不同并且在内存中的不同位置。 双重免费似乎是一个可能的候选者。您可以尝试做的一件事是查看正在释放的地址。您是否很幸运,并且在两次运行之间也是如此(例如,您可以在其上设置观察点)?或者你可以尝试识别它与其他对象的关系吗? 【参考方案1】:

您是否尝试过在 Visual Studio 调试器下运行这些测试用例? 调试器应该捕捉到这个异常,您可以验证调用堆栈并找到问题所在。

【讨论】:

异常发生在_free_base,他已经知道了。但调试器没有发现问题(即之前发生的堆损坏) 如果是这种情况,那么他应该只使用调试器并单步执行所有测试用例代码并找到产生异常的部分。 哇。这种幼稚的建议只能来自从未经历过远距离动作错误的人。我羡慕你。 Ben,你可能是对的,简单的步进是不够的。但这是第一个认为他应该做的。如果这没有帮助,那么他可以尝试在堆上设置写访问断点。如果使用调试器还不够,那么很少有工具可以提供帮助,例如 Windows 调试工具中的 Application Verifier 或 GFlags 和 PageHeap。有时,诸如 Rational Purify 之类的内存泄漏/损坏检测工具也会有所帮助。

以上是关于c++ 未处理的异常 - 如何调试的主要内容,如果未能解决你的问题,请参考以下文章

使用 Visual C++ 2008 时如何解决未处理的异常错误?

如何打破 Silverlight 中未处理的异常

来自未处理异常的 C++ 堆栈跟踪?

C++:XY.exe 中 0x0b9ec715 (XX.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000004

异常未处理:在 openCV 中的 cvtColor()

如何关闭“Visual Studio实时调试器”