【问题标题】:What is the difference between Debug and Release in Visual Studio?Visual Studio 中的调试和发布有什么区别?
【发布时间】:2010-09-26 22:36:56
【问题描述】:

可能重复 Debug Visual Studio Release in .NET

Visual Studio 中的 Debug 和 Release 有什么区别?

【问题讨论】:

    标签: .net visual-studio


    【解决方案1】:

    如果您浏览项目编译选项并比较它们,您会发现有什么不同。

    假设问题是关于本机/C++ 代码(从措辞中并不完全清楚):

    基本上,在“调试”中,所有代码生成优化都已关闭。一些库(例如STL)默认进行更严格的错误检查(例如调试迭代器)。生成更多调试信息(例如“编辑并继续”)。在代码中生成更多的东西来捕获错误(局部变量值设置为未初始化的模式,并使用调试堆)。

    【讨论】:

    • @Vilx:当我回答时,还没有 .net 标签,只有visualstudio。所以我假设它是 C++。
    【解决方案2】:

    大多数情况下,调试包含许多在调试时有用的额外信息。在发布模式下,这一切都被削减并换取了性能。

    【讨论】:

    • 1) 以下问题怎么办?一个 ASP.NET MVC 项目中有 3 个配置:基础 (web)、调试 (web.debug)、发布 (web.release)。假设我们通过转换到相应的配置(调试和发布)来设置调试和发布连接字符串。发布时,我们可以根据我们在发布对话框中的选择进行发布。但是,在运行应用程序时,尽管我选择了调试,但它使用了发布配置(因为我在基础和调试配置中设置了调试配置),这正常吗?
    • 2) 在Debug或Release模式下运行应用程序时,VS是使用base web config还是相应的web config(web.debug.confg or web.release.config) ?
    【解决方案3】:

    可能值得一提的是,构建标志允许不同的逻辑应该仅用于更改日志记录和“控制台”消息传递,但它可以滥用并极大地改变了不仅是低级别,而且是实际的业务逻辑。

    【讨论】:

    • "...戏剧性地改变...实际的业务逻辑"——对我来说听起来像是一个错误!我们有很多条件代码,很难理解。此外,条件代码标志的每个组合本质上是软件的不同版本,应进行测试以确保正确性和基本完整性。根据我的软件构建圣经“代码完成”,我们的“首要指令”是复杂性管理。 (这是我们要解决的第一个问题)。在不加选择地添加更多条件标志之前仔细考虑!
    • 我的上述评论并不是针对这个答案,特别是就最后一句话而言......这只是我认为来这里的读者应该阅读的另一件事。
    【解决方案4】:

    还请注意,例如,当使用 MFC 时,调试项目链接到不可再分发的 DLL 版本,例如 MFC90D.DLL,而发布版本链接到可再分发的版本,例如 MFC90.DLL。 这可能与其他框架类似。

    因此,您可能无法在非开发机器上运行调试构建应用程序。

    【讨论】:

    • 非常正确。在客户那里遇到过一次。在我的机器上工作 (TM)。
    • 你可以分发它们..(不知道你是否被允许)。它们必须位于应用程序的适当名称子文件夹中。
    • @Andreas 关于我的示例,“不可再分发”意味着 Microsoft 不允许允许分发它们。
    【解决方案5】:

    您可以看到的明显区别是二进制文件的大小。 Debug 版本生成的二进制文件比 Release 版本大。

    在 Debug 中编译时,符号表被添加到代码文件的编译对象中,这允许调试程序利用这些二进制文件并访问对象和变量的值。

    另一个明显的区别是,在发布模式下,二进制文件会简单地崩溃,而在调试模式下,如果你开始在 Visual Studio 中调试应用程序,你可以检查告诉你确切位置的调用堆栈错误的说法。

    【讨论】:

      【解决方案6】:

      最重要的是在Debug模式下没有优化,而在Release模式下有优化。这很重要,因为编译器非常先进,可以对代码进行一些非常棘手的低级改进。结果,您的代码中的某些行可能根本没有任何说明,或者有些可能会完全混淆。逐步调试是不可能的。此外,局部变量通常以神秘的方式进行优化,因此 Watches 和 QuickWatches 通常无法工作,因为变量被“优化掉了”。还有许多其他优化。尝试调试优化的 .NET 代码,您会看到的。

      另一个关键区别是,因此默认发布设置不会生成大量调试符号信息。这就是您可能已经注意到的 .PDB 文件,它允许调试器找出哪些汇编指令对应于哪一行代码等。

      【讨论】:

      • “因此,您的代码中的某些行可能会在没有任何说明的情况下留下,或者有些可能会混淆”。是的,使用堆栈帧来获取当前方法/属性的名称时犯了这个错误 - 并且许多属性在发布中内联......
      • “最重要的是在调试模式下没有优化” - 这是有争议的。最重要的是有调试信息可以让你调试。尽管这也可以存在于发行版中。
      • 我不知道哪个是默认模式(调试/发布)。一般来说,根据我的经验,所有项目都处于调试模式,安装团队将负责此版本以避免 pdb 文件,并引入优化。但是今天我遇到了一种情况,模式更改为发布,我无法使用断点中断代码。我尝试了很长的 1 小时做很多事情,最后我注意到这是由于当前编译模式的问题。 @Vlix- 感谢您的回答。
      • 这实际上帮助我解决了在调试符合默认设置的应用程序时尝试分析即时窗口中的符号时遇到的“当前上下文中不存在名称'变量'”问题发布配置。非常感谢!
      • 1) 以下问题怎么办?一个 ASP.NET MVC 项目中有 3 个配置:基础 (web)、调试 (web.debug)、发布 (web.release)。假设我们通过转换到相应的配置(调试和发布)来设置调试和发布连接字符串。发布时,我们可以根据我们在发布对话框中的选择进行发布。但是,在运行应用程序时,尽管我选择了调试,但它使用了发布配置(因为我在基础和调试配置中设置了调试配置),这正常吗?
      【解决方案7】:

      “Debug”和“Release”实际上只是一系列可能影响构建和调试的设置的两个标签。

      在“调试”模式下,您通常有以下内容:

      • 程序调试数据库文件,允许您在运行时非常密切地跟踪程序在源代码中的执行。
      • 所有优化都已关闭,这使您可以检查变量的值并跟踪可能已被优化掉或内联的函数
      • 一个 _DEBUG 预处理器定义,允许您编写与发布模式相比在调试模式下行为不同的代码,例如检测仅应在调试时使用的 ASSERT
      • 链接到也已编译并启用调试选项的库,这些库通常不会部署给实际客户(出于大小和安全原因)

      在“发布”模式下,优化已打开(尽管有多个选项可用)并且未定义 _DEBUG 预处理器定义。不过,通常您仍然希望生成 PDB 文件,因为当事情运行得更快时,能够在发布模式下“调试”非常有用。

      【讨论】:

      • “只有两个标签”——事实上,Visual Studio 让您能够创建更多! 这在测试程序时非常有用。例如,我最近为我的工作编写了一个程序,它从命令行接受文件名。我测试了我的命令行解析,但是一旦完成,我不想每天都弄乱 CMD 和文件名列表;我创建了一个配置,我可以使用条件编译来提供虚拟命令行值并测试程序的业务逻辑,这使我在程序开发中的迭代周期更快。
      【解决方案8】:

      另外,很明显,调试模式会创建很多额外的线程来帮助调试。无论您是否附加调试器,它们在整个过程的生命周期中都保持活动状态。请参阅我的相关问题here

      【讨论】:

      • 但仅适用于 .NET(不是 C++)?
      【解决方案9】:

      当我开发从现有 Release 构建配置复制的应用程序时,我也对这个问题感到好奇。

      我有一个开发人员,他对在调试模式下使用该应用程序很感兴趣,所以我想知道如何使这个存在的构建配置具有从 Release 配置复制的 ReleaseMyBuild 名称(因此应该具有所有设置发布优化)突然改变团队并成为调试版本,尽管构建配置名称令人困惑。

      我认为项目配置只是一个名称和一种方便的方式来选择 Joris Timmermans 提到的“全部设置”。我想知道究竟是什么设置使得名为“FOO”的构建配置作为优化的发布构建发挥作用。

      这是其中的一瞥。我从 Visual Studio 2010 中的空项目模板创建了一个新的 VCXPROJ。然后我复制并编辑了它,第一个保留了调试内容,第二个保留了发布内容。这是以相关差异为中心的差异...

      发布

      <PropertyGroup>
          <WholeProgramOptimization>true</WholeProgramOptimization>
      
      <ClCompile>
          <Optimization>MaxSpeed</Optimization>
          <FunctionLevelLinking>true</FunctionLevelLinking>
          <IntrinsicFunctions>true</IntrinsicFunctions>
      <Link>
          <EnableCOMDATFolding>true</EnableCOMDATFolding>
          <OptimizeReferences>true</OptimizeReferences>
      

      调试

      <PropertyGroup>
          <UseDebugLibraries>true</UseDebugLibraries>`
      
      <ClCompile>
          <Optimization>Disabled</Optimization>
      

      有趣的是,在链接部分,它们都将 GenerateDebugInformation 设置为 true。

      【讨论】:

        【解决方案10】:

        在调试配置中,您的程序使用完整的符号调试进行编译 信息和没有优化。优化使调试复杂化, 因为源代码和生成的关系 指令更复杂。

        你的程序的发布配置没有符号调试 信息并进行了全面优化。对于托管代码和 C++ 代码, 调试信息可以在 .pdb 文件中生成,具体取决于 使用的编译器选项。在以下情况下,创建 .pdb 文件会很有用 您稍后必须调试您的发布版本。

        参考微软doc

        【讨论】:

          【解决方案11】:

          在调试配置中,您的程序使用完整的符号调试信息进行编译,并且没有优化。优化使调试复杂化,因为源代码和生成的指令之间的关系更复杂。

          您的程序的发布配置没有符号调试信息,并且已完全优化。对于托管代码和 C++ 代码,可以在 .pdb 文件中生成调试信息,具体取决于使用的编译器选项。如果您以后必须调试发布版本,则创建 .pdb 文件会很有用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-10-22
            • 2011-07-17
            • 2012-07-01
            • 1970-01-01
            • 2010-10-08
            • 1970-01-01
            相关资源
            最近更新 更多