【问题标题】:Visual C++: Difference between Start with/without debugging in Release modeVisual C++:在发布模式下启动/不调试之间的区别
【发布时间】:2011-03-22 14:43:18
【问题描述】:

开始调试(F5不调试开始(CTRL-F5有什么区别? kbd>) 当代码以发布模式编译时?

我发现对于某些 C++ 代码,CTRL-F5F5 快 10 倍。如果我没记错的话,调试器附加到 F5 的执行进程,而不是 CTRL-F5。由于这是 Release 模式,编译后的代码没有任何调试信息。所以,如果我没有任何断点,那么两者的执行时间应该是相同的,不是吗?!

(假设发布和调试模式是您在创建新的 Visual C++ 项目时获得的典型配置。)

【问题讨论】:

    标签: visual-studio debugging visual-c++ release


    【解决方案1】:

    问题在于,如果 Windows 检测到您的程序正在调试器下运行,它就会进入一个特殊的调试堆。这似乎发生在操作系统级别,并且独立于您的编译的任何调试/发布模式设置。

    您可以通过设置环境变量来解决此“功能”:_NO_DEBUG_HEAP=1

    同样的问题已经让我发疯了一段时间;今天我发现了以下内容,这篇文章的来源: http://blogs.msdn.com/b/larryosterman/archive/2008/09/03/anatomy-of-a-heisenbug.aspx

    【讨论】:

    • 我正在用 C# 编程,我遇到了同样的问题。我解决了在项目属性 > 调试 > 命令行参数中添加 -hd 命令行选项的问题。谢谢!!
    【解决方案2】:

    “不调试就开始”只是告诉 Windows 以正常运行的方式启动应用程序。

    “开始调试”启动 VS 调试器并让它在调试器中运行应用程序。

    这实际上与调试/发布构建设置没有太大关系。

    当您构建应用的默认“调试”配置时,您将与发布构建有以下主要区别:

    • 发出的代码不会被优化,因此更容易调试,因为它更接近您的源代码
    • 编译器和链接器将输出一个 .PDB 文件,其中包含大量额外信息以帮助调试器 - 这些信息的存在与否对代码的性能没有影响,只是便于调试。
    • ASSERT 和 VERIFY 等条件宏在发布版本中将是无操作的,但在调试版本中是有效的。

    这些项目中的每一项都是独立且可选的!您可以打开或关闭其中的任何一项或全部,并且仍然在调试器下运行代码,您会发现生活没有那么容易。

    当您运行“带调试”时,由于以下几个原因,事情的表现会有所不同:

    • VS 调试器在启动时效率非常低,部分原因是 VS 中的所有内容都很慢 - 在 VS2010 之前的版本中,屏幕的每个像素都将被重新绘制大约 30 次,因为 IDE 进入调试模式时会出现大量闪烁和闪烁。
    • 根据配置的不同,调试器可能会在启动时花费大量时间来尝试为进程中的大量操作系统组件加载符号(即 PDB 文件) - 它可能会尝试获取这些文件网络,在某些情况下可能需要一段时间。
    • 您的应用程序通常执行的许多活动(加载 DLL、启动线程、处理异常)都会导致调试器收到警报。这既会减慢它们的速度,也会使它们倾向于按顺序运行。

    【讨论】:

    • Will:对于发布模式,如果没有断点,那么即使在调试器中,代码也不应该全速执行吗?在没有调试信息和断点的情况下,调试器到底在“做什么”会减慢它的速度?
    • Ashwin:我试图在回答的第二部分回答这个问题。调试器在代码的许多正常活动中被回调,这会导致延迟并且通常会丢失并行性。除此之外,它可能只是在系统启动时清除了系统中的每一块缓存,这意味着您的应用程序运行速度会变慢。
    • Ashwin:这里列出了您的应用程序在调试器下运行时会执行的操作:msdn.microsoft.com/en-us/library/ms679302%28VS.85%29.aspx
    【解决方案3】:

    IsDebuggerPresent()OutputDebugString() 的行为取决于是否附加了调试器。

    IsDebuggerPresent() 只是返回另一个值,因此您的程序可以对这个值做出反应并故意做出不同的行为。 OutputDebugString() 在没有附加调试器时返回得更快,所以如果它被调用很多次,你会发现程序在没有调试器的情况下运行得更快。

    【讨论】:

      【解决方案4】:

      运行“带调试”时使用调试堆,即使在发布模式下也是如此。这会导致使用大量 malloc/free 或 new/delete 的代码严重变慢,这可能发生在 C++ 代码中而您没有注意到它,因为库/类往往会对您隐藏这些内存管理内容。

      【讨论】:

      • 从未观察到这样的事情。发布构建完成后,它会链接到该非调试 CRT,因此调试堆没有机会到达。
      • @sharptooth:这里有两层在起作用。一个是 CRT,另一个是 Windows 本身,它也可能决定在调试堆上运行 any 进程。这篇博文比我能解释得更好:preshing.com/20110717/…
      • @Cygon:是的,但是操作系统级别通常会处理来自运行时堆内的大量分配,并且运行时堆本身会增加很多额外的开销,这会大大减慢操作系统级别的调试速度很难不注意到。
      • 这个答案是正确的,但没有比以前的答案添加任何内容,也没有提供任何解决方案。请参阅提及 _NO_DEBUG_HEAP 的答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 2011-09-02
      • 2016-12-16
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      相关资源
      最近更新 更多