我正在尝试调试一个问题,其中一个可执行文件在直接从 Visual Studio 执行时会产生可重复的输出(我想要),但在从命令提示符执行时不会产生可重复的输出。这是一个单线程应用程序,因此在时间方面不应该有任何奇怪的行为。
有人可以列举这两种环境之间可能存在的差异吗?
我确定实际的可执行文件是相同的——它们都是发布版本并且运行相同的 .exe 文件。
以下是环境和结果:
- 直接从命令提示符 (cmd) 运行:不可重复的输出
- 通过调试 (F5) 从 Visual Studio 运行:可重复输出
- 从 Visual Studio 运行而不进行调试 (Ctrl-F5):不可重复的输出
我知道工作目录可能不同,但我手动调整它以确保工作目录相同。
基于这些结果,看起来运行“带调试”(即使在发布版本中)以某种方式解决了问题。这是否指向一个可能的罪魁祸首?运行带有调试和不带调试的可执行文件有什么区别?
解决方案:正如接受的答案中指出的那样,调试堆是问题所在。问题是在我们代码的深处,有人在初始化之前访问了一个大数组的一部分。他们已经用 malloc 分配了内存并且没有将内存初始化为 0。调试堆(我假设)会用一些可重复的值填充数组,而当没有附加调试器时(即从命令行运行或使用Ctrl-F5)这些值更加随机,有时会导致程序行为的微小偏差。不幸的是,调整是如此微妙以至于几乎无法察觉,而有问题的记忆是在处理的第一个“帧”之后正确重置,但初始条件已经略有不同并且损坏已经造成。混沌理论在行动!感谢您的指导。
一个很好的调试技巧有帮助:编写一个自定义 malloc,立即用完全随机的数据填充内存。这样,您可以确保在使用它之前自己正确初始化它,否则每次运行它时您的结果都会(希望)疯狂——即使在调试模式下使用调试堆!