【问题标题】:How to diagnose Access Violation on application exit如何在应用程序退出时诊断访问冲突
【发布时间】:2010-09-27 15:11:11
【问题描述】:

我有一个正在尝试调试崩溃的应用程序。但是,由于以下几个原因,很难检测到问题:

  • 崩溃发生在关机时,这意味着有问题的代码不在堆栈中
  • 崩溃仅发生在发布版本中,这意味着符号不可用

崩溃是指以下异常:

0xC0000005: Access violation reading location 0x00000000.

您会使用什么策略来诊断这个问题?

到目前为止,我所做的是从我的程序中删除尽可能多的代码,直到我得到导致崩溃的最低限度。它似乎发生在静态链接到项目的代码中,所以这也无济于事。

【问题讨论】:

    标签: c++ wtl


    【解决方案1】:

    您甚至可以为发布版本制作符号文件。这样做,运行你的程序,附加调试器,关闭它,然后在调试器中查看崩溃的原因。

    【讨论】:

    • 该选项在visual c++ 6的链接选项卡中称为“生成调试信息”。
    【解决方案2】:

    您似乎在读取空指针 - 从来都不好。

    我不确定你在哪个平台上。 Linux下,可以考虑使用valgrind

    除了存在或不存在调试信息之外,您的发布版本与调试版本有何不同?

    您能否构建带有调试信息的静态链接代码?你能获得静态链接代码的调试版本吗?

    【讨论】:

    • 这是使用 WTL 的窗口。静态链接代码是我们的,是的,我可以创建它的调试版本。
    • 当我点击 WTL 标签时,我发现一切都与 Windows 相关...你确定在完整的调试版本中不会崩溃吗?
    【解决方案3】:

    我将使用的策略正是您所做的。尽可能多地删除代码,直到问题消失,然后重新添加最后一点并进行调试。

    但是,问题可能不是您的代码。需要注意的一件事 - 我们在 AIX 上发现了这个问题,即使您运行的是 Windows,它也可能类似。

    我们有一个第三方库,它动态加载另一个共享库,该库在其初始化例程中设置了一个 atexit 函数,以便在进程退出时调用。

    但是,当我们的应用程序加载和卸载这些共享库时,当进程退出时,共享库的 atexit 函数不再在内存中,我们转储了核心。

    这显示为访问冲突从 main() 返回后 因此,如果这就是发生在您身上的事情,那几乎可以肯定是同一类事情。 C RTL 启动代码将遍历 atexit 列表并调用其每个函数,无论您对它们做了什么。

    当然,如果它在 main() 退出之前崩溃,那么这是一个有争议的问题。

    您可以考虑一件事(实际上,在对跟踪和修复一个特别棘手的错误进行成本/收益分析之后,我们曾有一次这样做过):将调试版本作为您的产品发送。如果它没有崩溃,那么这可能是一个快速解决方案,可以在您闲暇时制定更可接受的解决方案时将产品推出。

    【讨论】:

    • 请记住,如果您开始分发调试运行时 dll,您可能会违反许可协议。例如,您不应该分发 MFC 运行时的调试版本
    猜你喜欢
    • 2019-03-03
    • 2013-12-05
    • 1970-01-01
    • 2016-04-04
    • 2022-06-10
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多