C++;程序神秘地冻结 我用MSVC++ 2010和GCC 4.2.1编写了一个C++ CLI程序(对于Mac OS X 10.6 64位,在Eclipse中)。 该程序在GCC+OSX下运行良好,大多数情况下在Windows下运行良好。但有时它会静静地冻结。命令行光标持续闪烁,但程序拒绝继续工作

C++;程序神秘地冻结 我用MSVC++ 2010和GCC 4.2.1编写了一个C++ CLI程序(对于Mac OS X 10.6 64位,在Eclipse中)。 该程序在GCC+OSX下运行良好,大多数情况下在Windows下运行良好。但有时它会静静地冻结。命令行光标持续闪烁,但程序拒绝继续工作,c++,visual-c++,gcc,crash,C++,Visual C++,Gcc,Crash,以下配置工作正常: 带有“发布”和“调试”配置的GCC。 具有“调试”配置的VC++ 该错误仅发生在Win 7 32位和64位下配置为“VC++且配置为“Release”的情况下。不幸的是,这是我的客户想要使用的配置-( 我已经检查了我的程序的上限和下限,并修复了所有内存泄漏。但是这个错误仍然发生。你知道我如何找到错误吗?调试版本通常会初始化所有分配的内存(MSVC用调试配置的0xCD填充它们)。可能您的类中有一些未初始化的值,在GCC配置和MSVC调试配置中,它会得到一个“幸运”值,但在MSV

以下配置工作正常: 带有“发布”和“调试”配置的GCC。 具有“调试”配置的VC++

该错误仅发生在Win 7 32位和64位下配置为“VC++且配置为“Release”的情况下。不幸的是,这是我的客户想要使用的配置-(


我已经检查了我的程序的上限和下限,并修复了所有内存泄漏。但是这个错误仍然发生。你知道我如何找到错误吗?

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

给你

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

  • 使用日志记录缩小程序崩溃时正在执行的代码部分。继续添加日志,直到缩小到足以看到问题为止
  • 在发布版本中启用调试信息(包括编译器和链接器);许多变量不会正确显示,但它至少应该为您提供合理的回溯(除非冻结是由于堆栈崩溃或堆栈溢出),如果您保持函数简短并且只做一件事,这通常就足够了
  • 内存泄漏不会导致冻结。但是,其他形式的内存滥用很可能会导致冻结。根据我的经验,当释放缓冲区时,溢出缓冲区通常会导致冻结,因为释放函数遵循损坏的块链。还要注意任何其他类型的未定义行为。在C/C++中有很多未定义的行为,并且通常表现为你期待在调试和完全随机优化时
  • 尝试在library下构建并运行程序,以检查缓冲区溢出。请注意:
    • 它需要大量的内存。我的意思是,很容易就需要上千倍的内存。所以你只能在简单的情况下进行测试
    • Microsoft标头往往会滥用其内部分配函数和不匹配,例如,常规malloc和内部调试免费(或相反的方式)。因此,可能会出现一些情况,您必须在duma one重新定义函数之前,将这些系统标头包含到duma one中,以仔细解决这些情况
  • 尝试为Linux构建程序并在下运行。这将检查除缓冲区溢出之外的更多问题,并且不会使用那么多内存(仅为正常情况的两倍,但速度较慢,约为20倍)

    • 谢谢大家,特别是科迪·格雷和米克,我找到了! 正如你们中的一些人建议的那样,我告诉VS生成调试信息并在发布配置中禁用优化。然后我启动程序并暂停它。或者我远程连接到正在运行的进程。这有助于我找到错误所在的区域。 原因是无限循环,这是由数组边界后面的读取和无效案例的遗漏排除引起的。这两种情况都导致运行时无法达到停止条件。最深奥的部分来自这样一个事实,即我的程序使用了一些随机值。
      这就是生活…

      您是否尝试将调试器附加到正在运行的应用程序?您仍然可以调试在“发布”中编译的应用程序模式。这将让您了解导致问题的代码部分。这对于我们使用水晶球进行远程调试基本上是不可能的。请看。它讨论了发行版和调试版之间的差异以及如何解决可能出现的许多问题。@Cody Gray:好建议。事实上,这不是e即使需要在调试器内运行程序/附加一个功能齐全的调试器。仅在冻结点使用SysInternals Process Explorer等可获得的堆栈跟踪可能提供一个合理的起点。这些都是正确的,但并不能真正解释“调试”的原因具有魔法值的版本不会崩溃。填充sentinel值的目的是为了更容易地调试问题。
      0xCD
      实际上没有指向内存中的有效位置,因此如果这是问题,您仍然会遇到硬崩溃。事实上,您保证会得到一个,这样您就可以调试它;这就是关键所在。我们对代码一无所知。指针可能已正确初始化,但某些标量未正确初始化,假设您将它们用作数组的索引。我曾经遇到过这样的情况:)@CodyGray:没有任何东西可以保证
      0xcdcdcd
      是无效指针,尽管它不太可能是。它不会等于malloc/new返回的任何内容,因为它没有对齐,但可能并不总是导致崩溃。