繁体   English   中英

单独的“调试”和“发布”版本?

[英]Separate 'debug' and 'release' builds?

我认为最好发布开发人员实际测试过的软件版本。 因此,我倾向于从项目/ makefile中删除“调试”目标,因此只能构建(测试,调试和发布)一个版本。

由于类似的原因,我不使用“断言”(另请参见断言是否总是不好? ...)。

那里的一个人认为,“调试”版本的原因是调试起来更容易:但是,我反驳说,您最终可能希望支持和​​调试所发布的内容,因此您需要构建一个发布版本,您可以在必要时进行调试...这可能意味着启用调试符号并禁用某些优化,即使在“发行版”版本中也是如此。

有人说“这真是个坏主意”。 这是我几年前制定的政策,但遭到了以下方面的追捧:

  • 一些开发人员正在测试其调试版本,但没有发布版本
  • 一些开发人员的写作错误,仅在发行版中显示
  • 该公司在测试不足后发布了发行版本( 是否完全足够?)
  • 被调用以调试发行版

从那时起,我已经看到其他多家开发商店都遵循这种做法(即没有单独的调试和发布版本)。

你有什么政策?

拥有单独的调试和发行版本是一个好主意,因为它确实使开发更容易。

但是调试版本应该仅用于开发,而不是用于测试。 您仅测试发布版本。 而且您不使用开发人员来测试那些构建,而是使用测试人员。

这是一项简单的政策,兼顾了两者的优点。

编辑:针对评论,我认为很明显,调试和发布版本(可以)生成不同的代码。 考虑“ -DDEBUG”与“ -DNDEBUG”以及“ #if defined(DEBUG)”等。

因此,测试最终交付的代码至关重要。 如果您确实在调试和发行版本中生成了不同的代码,则意味着要进行两次测试-不管是否由同一个人测试过。

但是,调试符号并不是一个大问题。 始终使用调试符号进行构建,保留未剥离的二进制文件的副本,但释放剥离的二进制文件。 只要您以某种方式用构建号标记每个二进制文件,您就应该始终能够确定哪个未剥离的二进制文件与您必须调试的剥离的二进制文件相对应。

如何从外部源中剥离二进制文件并在调试器中加载符号取决于平台。

这可能很小,但这加起来了其他人在这里所说的话。 建立QA测试版本的优点之一是,随着时间的推移,软件开发人员的内置调试和日志记录功能将随着开发人员的需求而发展,这些开发人员需要弄清楚为什么QA中出现问题。

开发人员越需要调试发布版本,则当客户开始遇到问题时,您将拥有更好的工具。 当然,作为开发周期的一部分,开发人员没有理由进行发行版本的工作。

另外,我不知道有哪个软件公司具有足够长的周期来承担将QA从调试切换到发布的开销,而该公司在版本的测试期中途才完成。 必须执行完整的质量检查周期通常很少发生。

我们的政策是让开发人员从事Debug构建,但其他所有人(质量保证,BA,销售等)都运行发行版。 昨天我不得不修复一个仅出现在发行版中的错误,构建该程序是显而易见的,因为它只出现在发行版中

这是这家商店的第一个,我来这里已有18个月左右。

令人毛骨悚然的地方是Release版本与调试版本做不同的事情-是的,我去过地狱,并在一些非常古老,非常笨拙的生产代码中看到了这一点。

如果配置之间的唯一区别是调试符号和优化,我认为没有理由不同时拥有两者。

因此,您需要构建一个发行版,必要时可以进行调试...这可能意味着即使在“发行版”构建中,也要启用调试符号并禁用某些优化。

嗯...听起来您正在对我进行调试...对吧?

您出错的部分是以下语句:

我认为最好发布开发人员实际测试过的软件版本

开发人员不测试代码。 测试测试代码。

您的单元测试应该测试所有构建配置。 不要让开发人员只用一只手绑在背后,而是让他们使用那里可用的所有调试工具。 调试版本就是其中之一。

关于断言:断言的使用很大程度上取决于您是否按合同进行编程。 如果这样做,则断言仅在调试版本中检查合同。

根据我在链接线程中的回答,出于非常相似的原因,我们还使用相同的构建进行调试和发布。 与算法级别的手动优化相比,从优化器获得的10%-20%的性能提升往往很小。 单个版本可以消除许多潜在的错误。 特别;

  • 未初始化的变量和较小的缓冲区溢出可能最终导致调试和优化发行版的结果截然不同。

  • 即使有可用的符号信息,由于对象与源不匹配,调试优化发行版也可能很困难,例如,变量可能已被优化,代码可能已重新排列。 因此,在经过测试的发行版中报告的错误可能更难追踪,因此非常耗时。

在自动回归测试下比较了未优化和优化的构建之后,在我的案例中,优化提供的性能提升没有提供足够的额外价值来拥有两个构建。 可能值得注意的是,我开发的软件非常占用CPU(例如,创建和处理大型曲面模型)。

使用Java开发时,我讨厌非调试版本。 引发异常时,您不会获得任何行信息,这使得很难甚至根本无法跟踪错误。 而且,在Java 5或更高版本中,调试和非调试之间的运行时差异约为5%,因此这实际上没有问题,对于当今的硬盘,大小不再重要。

使用调试版本的好处是:

  • 堆栈跟踪包含您需要的所有信息
  • 可以检查变量
  • 如果您在生产中遇到问题,则可以简单地附加到正在运行的进程,而不必先停止服务器来安装调试版本。
  • 您不会被聪明的优化错误所困扰
  • 构建更简单(仅一个工件)

开发人员使用调试版本,QA进行工作,其他所有人都使用发行版,我们将其称为“生产”。 这样做的主要优点是,在调试版本中,我们可以添加许多额外的代码和断言。 有些对象包含多余的信息,除非在调试器中查看代码,否则这些信息无用。 一些对象会定期验证自己,以确保所有状态信息都是一致的。 这些事情使调试版本变慢了很多,但它们帮助我们找到了在生产环境中无法发现的所有错误。

就像我说的,我们所有的质量保证和性能测试都使用生产版本,并且偶尔会遇到在生产中出现但在调试中没有出现的问题。 但是它们相对较少,并且作为开发人员,调试调试版本而不是生产版本的优势远远超过了这个问题。

我认为这取决于项目规模以及所使用的构建系统和测试的类型。

如果您拥有一个自动构建系统,并且在给定构建上运行单元和功能测试很简单,那么对于多种构建类型,您永远都不会有任何问题。

出于您在问题中列出的所有原因,我一直订阅“运送您要调试的东西,以便您可以调试所运送的东西”的方法。

我认为该讨论缺少非常重要的一点:

这实际上取决于它是哪种项目!

如果您创建本机(C / C ++)项目,则实际上将被迫创建调试版本,这仅仅是因为编译器优化可能使调试在某些情况下几乎变得不可能。

如果创建Web应用程序,您可能希望仅拥有一个可以在运行时启用日志记录功能的构建(尽管“ build”对于某些Web应用程序具有误导性)。

尽管本机C ++项目和PHP Web应用程序显然不是存在的所有项目,但我希望我能理解我的观点。

PS:在为C#开发时,您会遇到麻烦,因为尽管使用调试版本会禁用编译器优化,但根据我的经验,您不会遇到与C ++差不多的差异

在这里,我们以调试模式进行开发,并以发布模式进行所有单元测试。 我们是一家小商店,只有几个(不到12个)应用程序,可以支持Classic ASP,ASP.Net,VB.Net和C#。 我们还有专职人员来处理所有测试,将调试后的问题交还给开发人员。

我们总是建立两者,甚至从未考虑过不这样做。 启用调试选项会增加代码大小并降低性能,这可能不是测试时软件类型的问题,但是如果客户正在运行您的代码以及其他5个应用程序该怎么办...

可以使用自动化测试来解决测试问题,以便在您准备发布时可以轻松地测试发布版本。 开发人员或公司未能正确测试发布版本的失败并不是发布和调试版本的思想失败,而是开发人员和/或公司的失败。

关于您的最后一点,我从未被要求调试发布版本,只是为了修复它...

这是一个权衡。 鉴于CPU周期便宜并且越来越便宜,而人工周期却很昂贵,因此仅维护大型复杂程序的单个版本(调试(山墙)版本)在很大程度上是有意义的。

始终使用断言总是比不使用断言更安全的策略。 如果生成单独的调试和发行版本,请重新启用所需的任何#define d符号,以确保在发行版本中也启用了断言。

我认为折衷很简单:是的,只有发行版本,您才能真正测试实际交付的产品。 另一方面,您确实要为开发人员的调试和/或用户的性能降低付出代价,因此您需要检查这两种情况。

在大多数中型到大型项目中,易于调试将最终确保为用户提供更好的产品。

看到这里您最有争议的编程观点是什么?

引用:

意见:“调试”和“发布”版本之间永远不会有不同的代码

主要原因是发布代码几乎从未经过测试。 最好在野外运行相同的代码以进行测试。

通过删除“调试目标”,您将迫使开发人员在软件的发行版本上进行调试。 实际上,这可能意味着两件事:

1)“发布版本”将禁用优化功能(否则,开发人员无法使用调试器)

2)没有任何构建将具有特殊的PREPROCESSOR宏来更改其执行。

因此,您真正要做的是合并发行和调试配置,而不是仅消除“调试”模式。

我个人是通过iOS开发完成此操作的,没有任何不良影响。 在我们编写的代码中花费的时间少于实际发生的时间的1%,因此优化并不是重要的贡献者。 在这种情况下,它们确实确实导致了bug的增加,但是即使不是,它们也是如此,以一种方法进行测试,然后使用不同的代码进行质量检查的想法,仅引入了一个考虑问题的因素。

另一方面,在某些情况下,优化是必要的,它们是有用的,甚至有足够的时间来测试这两者。 通常,调试和发布之间的更改很小,以至于根本不会引起任何问题。

如果您有一个真正的QA小组可以指望它进行全面的测试,那么我会说制作调试版本,直到您接近发行版为止,然后确保在相同的版本上完成完整的QA周期。走出去。

尽管在至少一种情况下,我们发布了仍然包含一些调试代码的东西。 唯一的结果是运行速度稍慢并且日志文件非常大。

在我的公司中,我们同时具有Debug和Release。 -开发人员使用调试版本正确查找和修复错误。 -我们正在使用TDD,因此我们在服务器上运行了一个大型测试套件,用于测试调试和发布版本配置以及我们拥有的64/32版本。

因此,如果使用“调试”配置有助于开发人员更快地发现错误,则没有理由不使用它-当代码进入服务器(待进一步测试)或检查代码时,我们将使用“发布”。

很久以前,我学会了使用.PDB文件构建发行版本,以便可以调试发行版本。 许多程序员往往会忘记的是,当您运行调试版本时,如果关闭了所有优化功能,则您将完全调试另一个程序。 它的行为可能与发行版本相似(大部分情况下),但它仍然是与发行版本不同的程序。

此外,调试发布版本并不困难。 而且,如果您有故障转储,则无论如何都必须能够做到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM