使用Visual Studio调试器运行可执行文件与不使用调试器的差异 [英] Differences between running an executable with Visual Studio debugger vs without debugger

查看:222
本文介绍了使用Visual Studio调试器运行可执行文件与不使用调试器的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



是相同的 - 他们都是发行版本,并运行相同的.exe文件。



以下是环境和结果:


  1. 直接从命令提示符(cmd):不可重复输出

  2. 使用调试从Visual Studio运行(F5):可重复输出

  3. 从Visual Studio运行而不调试-F5):不可重复输出



我知道工作目录可能不同,但我手动调整请确保工作目录是相同的。



基于这些结果,它看起来像运行使用调试(即使在发布版本)以某种方式解决问题。这是否指向一个可能的罪魁祸首?解决方案:正如在接受的答案中指出的,调试堆是问题。问题是,在我们的代码的深处,有人在初始化之前访问大数组的部分。他们用malloc分配内存,没有将内存初始化为0.调试堆(我假设)用一些可重复的值填充数组,而当调试器没有附加时(即从命令行运行或者Ctrl-F5),值更随机,有时会导致程序行为的微小偏差。不幸的是,调整是如此微妙,几乎是不引人注意的,并且问题的存储器在第一个框架处理后正确复位,但初始条件已经略有不同,损害已经完成。混沌理论在行动!感谢您的指导。



一个伟大的调试提示帮助了:写一个自定义malloc,立即用完全随机的数据填充内存。这样,你可以确保你在使用它之前你自己正确地初始化它,否则你的结果将(希望)疯狂每次你运行它 - 即使在调试堆的调试堆!

解决方案

如果进程在调试器下启动,Windows Heap的行为会有所不同。要禁用此行为(为了在调试时找到问题),请将_NO_DEBUG_HEAP = 1添加到环境中(例如这个问题)。



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


I'm trying to debug an issue in which an executable produces repeatable output (which I want) when executed directly from Visual Studio, but does not produce repeatable output when executed from the command prompt. It's a single-threaded application, so there shouldn't be any strange behaviour there in terms of timing.

Can somebody enumerate what possible differences could be between the two environments?

I'm sure the actual executable is the same -- they're both release builds and are running the same .exe file.

Here are the environments and the outcomes:

  1. Run directly from command prompt (cmd): Non-repeatable output
  2. Run from Visual Studio with Debugging (F5): Repeatable output
  3. Run from Visual Studio without Debugging (Ctrl-F5): Non-repeatable output

I know that the working directory can possibly be different, but I'm manually adjusting that to make sure that the working directory is identical.

Based on these results, it looks like running "with Debugging" (even in a Release build) somehow fixes the problem. Does this point to a likely culprit? What are the differences between running an executable with debugging and without?

SOLUTION: As pointed out in the accepted answer, the debug heap was the issue. The problem was that deep in the bowels of our code, somebody was accessing parts of a large array before they were initialized. They had allocated memory with a malloc and had not initialized the memory to 0. The debug heap would (I assume) fill the array with some repeatable value, whereas when the debugger wasn't attached (i.e. when run from the command line or with Ctrl-F5) the values were more random and would sometimes cause tiny deviations in the behaviour of the program. Unfortunately, the adjustment was so subtle as to almost be unnoticeable, and the memory in question was properly reset after the first "frame" of processing, but the initial conditions were already slightly different and the damage had been done. Chaos theory in action! Thanks for the guidance.

One great debugging tip that helped out: write a custom malloc that immediately fills memory with completely random data. That way, you can make sure you're properly initializing it yourself before using it, otherwise your results will be (hopefully) crazy every time you run it -- even in debug mode with the debug heap!

解决方案

Windows Heap behaves differently if process is started under the debugger. To disable this behavior (in order to find a problem while debugging) add _NO_DEBUG_HEAP=1 to environment (like in this question).

Alternatively you can attach to process early in program execution. Heap will not enter the debug mode then. Add DebugBreak() line somewhere in the beginning of the execution, run with Ctrl+F5, and start debugging when asked to.

这篇关于使用Visual Studio调试器运行可执行文件与不使用调试器的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆