我正在尝试调试一个问题,在该问题中,当直接从Visual Studio执行时,可执行文件会产生可重复的输出(我想要的),但是从命令提示符处执行时,不会产生可重复的输出。它是一个单线程应用程序,因此在计时方面不应该有任何奇怪的行为。

有人可以列举两种环境之间可能存在的差异吗?

我确定实际的可执行文件是相同的-它们都是发布版本,并且运行相同的.exe文件。

以下是环境和结果:

  • 直接从命令提示符(cmd)运行:不可重复的输出
  • 从Visual Studio中通过调试(F5)运行:可重复输出
  • 从Visual Studio运行,无需调试(Ctrl-F5):不可重复的输出

  • 我知道工作目录可能会有所不同,但是我正在手动进行调整以确保工作目录相同。

    根据这些结果,看起来“以调试方式运行”(即使在Release版本中)似乎可以解决该问题。这是否表明可能是罪魁祸首?有调试和无调试运行可执行文件有什么区别?

    解决方案:如公认的答案中指出,调试堆就是问题所在。问题在于,在我们代码的深处,有人在初始化之前访问了大型数组的各个部分。他们已经使用malloc分配了内存,并且没有将内存初始化为0。调试堆(我认为)会用一些可重复的值填充数组,而当调试器未连接时(即,从命令行运行或使用Ctrl-F5)值是随机的,有时会导致程序行为的微小偏差。不幸的是,调整是如此微妙以至于几乎无法察觉,并且在处理的第一个“帧”之后适当地重置了所讨论的内存,但是初始条件已经稍有不同,并且已经造成了损坏。混沌理论在行动!感谢您的指导。

    很有帮助的调试技巧:编写自定义malloc,立即用完全随机的数据填充内存。这样,您可以确保在使用前自己进行了正确的初始化,否则每次运行时您的结果都会(希望)发疯-即使是在带有调试堆的 Debug模式下!

    最佳答案

    Windows Heap behaves differently if process is started under the debugger.要禁用此行为(以便在调试时发现问题),请将_NO_DEBUG_HEAP = 1添加到环境中(例如this question中)。

    或者,您可以在程序执行的早期就附加到进程。堆将不会进入 Debug模式。在执行开始的某处添加DebugBreak()行,使用Ctrl + F5运行,并在要求时开始调试。

    10-07 19:28
    查看更多