如何在应用程序退出时诊断访问冲突

时间:2008-12-18 22:39:35

标签: c++ wtl

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

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

崩溃,我的意思是以下例外:

0xC0000005: Access violation reading location 0x00000000.

您将使用什么策略来诊断此问题?

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

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:1)

你似乎有一些东西读取空指针 - 永远不会好。

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

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

您可以使用调试信息构建静态链接代码吗?你能获得静态链接代码的调试版本吗?

答案 2 :(得分:1)

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

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

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

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

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

当然,如果它在main()退出之前崩溃,那么这是一个没有实际意义的点。

您可以考虑的一件事(我们实际上已经在跟踪和修复一个特别棘手的错误的成本/收益分析之后完成了这一点):发送调试版本作为您的产品。如果它没有崩溃,这可能是一个快速解决方案,以便在您在闲暇时使用更可接受的解决方案时将产品送到那里。