我有一个正在尝试调试崩溃的应用程序。但是,由于以下几个原因,很难检测到该问题:
- 崩溃发生在关闭时,这意味着有问题的代码不在堆栈中
- 崩溃仅发生在发布版本中,这意味着符号不可用
崩溃是指以下异常:
0xC0000005: Access violation reading location 0x00000000.
你会使用什么策略来诊断这个问题?
到目前为止,我所做的是从我的程序中删除尽可能多的代码,直到我得到导致崩溃的最低限度。它似乎发生在静态链接到项目的代码中,所以这也无济于事。
您甚至可以为发布版本制作符号文件。这样做,运行你的程序,附加调试器,关闭它,然后在调试器中查看崩溃的原因。
你似乎有一些读取空指针的东西 - 从来没有好过。
我不确定你在哪个平台上。在 Linux 下,你可以考虑使用valgrind
.
除了存在或不存在调试信息之外,您的发布版本与调试版本有何不同?
您可以构建带有调试信息的静态链接代码吗?您可以获得静态链接代码的调试版本吗?
我将使用的策略正是您所做的。删除尽可能多的代码,直到问题消失,然后重新添加最后一位并调试它。
但是,可能不是您的代码有问题。需要注意的一件事 - 我们在 AIX 上发现了这个问题,即使您运行的是 Windows,它也可能类似。
我们有一个第三方库,它动态加载另一个共享库,该库在其初始化例程中设置了一个 atexit 函数,以便在进程退出时调用。
然而,当我们的应用程序加载和卸载这些共享库时,当进程退出时,共享库的 atexit 函数不再在内存中,我们转储了核心。
这在从 main() 返回后显示为访问冲突,因此,如果这就是发生在您身上的事情,那几乎可以肯定是同一类事情。C RTL 启动代码将遍历 atexit 列表并调用其每个函数,无论您对它们做了什么。
当然,如果它在 main() 退出之前崩溃,那么这是一个有争议的问题。
您可以考虑的一件事(在跟踪和修复一个特别棘手的错误的成本/收益分析之后,我们实际上曾经这样做过):将调试版本作为您的产品发送。如果它没有崩溃,那么当您在闲暇时研究更可接受的解决方案时,这可能是一个快速修复产品的方法。