3

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

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

崩溃是指以下异常:

0xC0000005: Access violation reading location 0x00000000.

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

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

4

3 回答 3

5

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

于 2008-12-18T23:15:29.777 回答
1

你似乎有一些读取空指针的东西 - 从来没有好过。

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

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

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

于 2008-12-18T22:47:53.247 回答
1

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

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

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

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

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

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

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

于 2008-12-18T23:51:08.597 回答