2012-05-25 63 views
1

我用MS VC++ 2010和GCC 4.2.1编写了一个C++ CLI程序(对于Mac OS X 10.6 64位,在Eclipse中)。 该程序在GCC + OS X下运行良好,大部分时间在Windows下运行。但有时它会静静地冻结。命令行光标保持闪烁,但程序拒绝继续工作。C++程序严重冻结

以下配置工作正常: 具有'Release'和'Debug'配置的GCC。 VC++ with'Debug'configuration

错误只发生在Win 7 32位和64位下配置'VC++'Release'配置'。不幸的是,这是我的客户想要配置的配置;-(

我已经检查了我的程序高低,并修复了所有的内存泄漏,但是这个错误仍然存​​在,你有什么想法我怎么能找到这个错误?

+1

您是否尝试过将调试器附加到正在运行的应用程序?您仍然可以调试以“发布”模式编译的应用程序。这会让你对代码的哪一部分导致问题有所了解。对于我们来说,使用我们的水晶球进行远程调试基本上是不可能的。 –

+1

看看[这个链接](http://www.flounder.com/debug_release.htm)。它讨论了版本和调试版本之间的区别以及如何解决可能出现的许多问题。 – MikMik

+0

@Cody Gray:很好的建议。实际上,甚至不必在调试器中运行该程序/附加全功能调试器。仅可获得例如堆叠迹线与SysInternals进程资源管理器在冻结点可能会提供一个合理的起点。 –

回答

1
  • 使用日志记录来缩小程序在崩溃时执行哪部分代码。继续添加日志,直到您缩小到足以查看问题。
  • 在发布版本(编译器和链接器)中启用调试信息;很多变量都不会正确显示,但它至少应该给你一个明智的回溯(除非因堆栈砸碎或堆栈溢出而导致冻结),如果你保持功能简短并且只做一件事,通常就足够了。
  • 内存泄漏不能导致死机。其他形式的记忆滥用却很可能发生。根据我的经验,当缓冲区被释放时,缓冲区经常会导致死机,因为自由功能跟随了损坏的区块链。另外注意任何其他种类的未定义行为。在C/C++中有很多它,它通常在调试时表现得如你所期望的那样,并且在优化时是完全随机的。
  • 尝试构建并运行DUMA库下的程序以检查缓冲区溢出。尽管如此:
    • 它需要一个lot的内存。我的意思是简单地多一千倍。所以你只能在简单的情况下测试。
    • Microsoft标头倾向于滥用其内部分配功能和不匹配,例如正常的malloc和内部的__debug_free(或其他方式)。因此,在重新定义函数之前,可能需要通过将这些系统头文件包含到duma中来小心解决一些情况。
  • 尝试构建Linux的程序并在Valgrind下运行该程序。除缓冲区溢出之外,这将检查更多的问题,并且不会占用太多内存(只是正常情况的两倍,但速度较慢,大约为20倍)。
1

调试版本通常初始化所有分配的内存(MSVC使用0xCD用调试配置填充它们)也许你的类中有一些未初始化的值,GCC配置和MSVC调试配置会得到一个“幸运”值,但在MSVC发布它没有。

这里是the rest of the magic numbers used by MSVC

因此,寻找未初始化的变量,属性和已分配的内存块。

+0

这已经足够了,但并不能真正解释为什么带有魔法值的“调试”版本*不会崩溃。填充哨兵值的目的是让您更容易地调试问题。 “0xCD”实际上并不指向内存中的有效位置,所以如果出现这种问题,您仍然会遇到严重的故障。事实上,你*保证*得到一个,所以你可以调试它;这就是整个观点。 –

+1

我们对代码一无所知。这些指针可能会被正确初始化,但是一些标量并不是,并且假设您将它们用作数组的索引。它发生在我身上:) – wrock

+0

@CodyGray:没有什么能够保证'0xcdcdcdcd'是无效指针,尽管它不太可能。它不等于malloc/new返回的任何内容,因为它没有对齐,但它可能不会导致崩溃。 –

0

谢谢大家,特别是Cody Gray和MikMik,我发现了! 正如你们推荐的那样,我告诉VS在发布配置中生成调试信息并禁用优化。然后我启动了程序并暂停了它。或者我远程连接到正在运行的进程。这帮助我找到了错误所在的地区。 原因是无限循环,这是由读取数组边界后的读取以及缺少无效情况的排除引起的。两者都导致运行时无法达到停止条件。神秘的部分来自事实,我的程序使用了一些随机值。 这就是生活...