如何解决仅在客户端系统上发生的非法内存访问崩溃问题?

时间:2015-12-02 19:13:19

标签: c++ windows debugging

我正在尝试解决我们的应用程序问题,该问题仅发生在属于我们某个客户的特定服务器上。

应用程序有时会崩溃,核心文件显示非法内存访问。我怀疑其原因是malloc函数出现了某种失败。它可能返回一个NULL指针,但是当发生这种情况时,机器仍然有足够的可用内存。我的理论是内存过于分散,当它试图分配更多的内存(18MB)时,它可能会失败。

我可以采取哪些措施来解决此问题?例如,Windows在内存分配失败时是否记录任何信息?或者只是忽略它?

有问题的服务器正在运行Windows Server 2008 R2并且Windows事件日志服务正在运行。

此时我无法包含任何代码,因为我不知道应用程序的哪个部分导致了问题。我怎样才能缩小范围呢?

2 个答案:

答案 0 :(得分:1)

没有。 Windows Even Log是您必须在代码中设置和使用的东西,通常用于Windows服务。

请显示一段代码片段,演示如何分配内存。

应该通过检查返回的值是否为NULL来错误地检查对malloc的调用。

如果您不确定哪个对malloc的调用失败,那么您最好选择投资一个好的分析器。我使用英特尔Parallel Studio取得了很大的成功,但它并不便宜。还要记住,我曾尝试过的每个探查器都无法在COM边界上工作。

“非法内存访问”不一定是分配内存失败。它可能是各种各样的事情。您需要将软件分解为可测试单元,并在担心如何解决问题之前查明问题。

编辑(问题修订后): 你真的限制自己使用约束“我们不能改变代码”

您应首先在malloc或new的每个文件中进行搜索,并确保检查结果。

您还可以选择关闭优化,导出符号,创建构建,安装调试工具以及远程调试,同时逐步调试代码以缩小问题的范围。但是,如果您有一系列要重现的步骤,那么这可能只是一个选项。由于代码中的错误,这些类型的内存问题通常是随机的。它可能只显示在一个版本而不是另一个版本中,但错误仍然存​​在。

您也可以远程进行配置,但对整个应用程序或服务进行概要分析会产生几乎无法获得的结果。软件应分解为单元可测试部件,然后分解为集成可测试部件。如果不是,那就是你支付的价格(即使不是你的错)。

答案 1 :(得分:1)

这是一个经典的调试情况。您有立即失败(非法内存访问),您需要回到根本原因。如果你在汇编中进行调试,你很可能会看到一个带有无效内存ptr的寄存器,用于访问内存。在确定了寄存器之后,你就可以向后工作,看看寄存器从哪里获得了它的价值。

如果它从内存分配调用中得到它的值,那么你的理论可能是正确的。

如果它从另一个你不知道它的值应该是什么的寄存器或内存位置得到它的值,那么你有一个“中间原因”。第二个寄存器或存储器位置是第一个寄存器具有无效存储器ptr的原因。

你继续通过中间原因恢复工作,直到找到根本原因 - 有人可以解决的问题。您可能需要长时间调用堆栈才能找到下一个中​​间原因,或者在特定功能中返回很长时间。如果你运气不好,根本原因可能是记忆覆盖或竞争条件或其他阻碍了主要是演绎过程的事情。

如果您可以进行源代码调试(可能没有第三方应用程序),您可以避免使用汇编语言。

顺便说一句,如果你确实有第三方应用程序,那么即使你确实找到了根本原因,也很有可能你无法自己解决问题。您可能需要软件供应商的更新。

如果该软件是开源的,您可以有更多选择。您可以下载源代码,修复错误并重建。或者您可以将修复程序推回到OSS项目中。