单独的“调试” 并“释放” 构建?
我认为最好发布您的开发人员实际测试过的软件版本; 因此,我倾向于从项目/makefile 中删除“调试”目标,这样就只能构建(并测试、调试和发布)一个版本。
出于类似的原因,我不使用“断言”(另请参阅断言总是不好吗?< /a> ...)。
那里的一个人认为“调试”版本的原因是它更容易调试:但是,我反驳说,您最终可能希望支持和调试您发布的任何内容,因此您需要构建一个版本如果需要,您可以进行调试...这可能意味着启用调试符号,并禁用某些优化,即使在“发布”版本中也是如此。
还有人说“这是一个坏主意”; 这是我几年前制定的一项政策,被以下因素所困扰:
- 一些开发人员测试他们的调试版本,而不是发布版本
- 一些开发人员编写的错误仅出现在发布版本中
- 公司在测试不充分后发布了发布版本(是<曾经完全足够吗?)
- 被要求调试发布版本
从那时起,我看到不止一个其他开发商店遵循这种做法(即没有单独的调试和发布版本)。
你们的政策是什么?
I think it's better to release the version of the software which your developers actually tested; I therefore tend to delete the 'debug' target from the project/makefile, so that there's only one version that can be built (and tested, and debugged, and released).
For a similar reason, I don't use 'assertions' (see also Are assertions always bad? ...).
One person there argued that the reason for a 'debug' version is that it's easier to debug: but, I counter-argued that you may eventually want to support and debug whatever it is you released, and so you need to build a release which you can if necessary debug ... this may mean enabling debug symbols, and disabling some optimizations, even in the 'release' build.
Someone else said that "this is such a bad idea"; it's a policy I evolved some years ago, having been burned by:
- Some developers' testing their debug but not release versions
- Some developers' writing bugs which show up only in the release version
- The company's releasing the release version after inadequate testing (is it ever entirely adequate?)
- Being called on to debug the release version
Since then I've seen more than one other development shop follow this practice (i.e. not have separate debug and release builds).
What's your policy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
这可能很小,但它增加了其他人在这里所说的内容。 进行 QA 测试发布版本的优点之一是,随着时间的推移,由于需要找出 QA 中出现问题的原因的开发人员的需求,软件的内置调试和日志记录功能将会进步。
开发人员需要调试发布版本的次数越多,当客户开始遇到问题时,您将拥有更好的工具。
当然,开发人员没有理由将发布版本作为开发周期的一部分。
另外,我不知道有哪家软件公司有足够长的周期来承担在版本测试期间中途将 QA 从调试版本切换到发布版本的开销。 必须进行完整的质量检查周期是经常发生的事情,但很少发生。
This might be minor, but it adds up to what others have said here. One of the advantages of having QA test release builds is that over time the built in debugging and logging capabilities of your software will advance due to the needs of developers who need to figure out why things are going wrong in QA.
The more the developers need to debug release builds, the better tools you'll have later when customers start having issues.
Of course, no reason for developers to work on release builds as part of the development cycle.
Also, I don't know any software company that has long enough cycles to afford the overhead of switching QA from debug to release builds halfway through a version's testing period. Having to do a full QA cycle is something that all too often happens pretty rarely.
单独的调试和发布版本是一个好主意,因为它确实使开发变得更容易。
但调试版本应该仅用于开发,而不是用于测试。 您仅测试发布版本。 而且您不使用开发人员来测试这些构建,而是使用测试人员。
在我看来,这是一个简单的政策,可以两全其美。
编辑:作为对评论的回应,我认为调试和发布版本显然可以生成不同的代码。 想想“-DDEBUG”与“-DNDEBUG”和“#if Defined(DEBUG)”等。
因此,测试最终发布的代码至关重要。 如果您确实在调试和发布版本中生成不同的代码,则意味着测试两次 - 无论是否由同一个人测试。
然而,调试符号并不是一个大问题。 始终使用调试符号进行构建,保留未剥离的二进制文件的副本,但释放剥离的二进制文件。 只要您以某种方式用内部版本号标记每个二进制文件,您应该始终能够识别哪个未剥离的二进制文件与您必须调试的剥离的二进制文件相对应...
如何从外部源剥离二进制文件并在调试器中加载符号是平台相关的。
Having separate debug and release builds is a good idea, because it does make development easier.
But debug builds should be for development only, not for testing. You test release builds only. And you don't use developers to test those builds, you use testers.
It's a simple policy that gives the best of both worlds, IMO.
Edit: In response to a comment, I think it's obvious that debug and release builds (can) generate different code. Think "-DDEBUG" vs. "-DNDEBUG", and "#if defined(DEBUG)", etc.
So it's vital that you test the code that you end up shipping. If you do generate different code in debug and release builds, that means testing twice - regardless of whether or not it's tested by the same person.
Debug symbols are not that big an issue, however. Always build with debugging symbols, keep a copy of the unstripped binary, but release a stripped binary. As long as you tag each binary with a build number somehow, you should always be able to identify which unstripped binary corresponds to the stripped binary that you have to debug...
How to strip binaries and load symbols in your debugger from an external source is platform-dependent.
我们的政策是让开发人员致力于调试版本,但其他人(QA、BA、销售等)则运行发布版本。
昨天我必须修复一个仅在发布版本中出现的错误,很明显发生了什么,因为它只在发布版本中出现。这
是这家商店的第一个错误,我已经在这里 18 个月左右了。
当发布版本与调试版本执行不同的操作时,事情就会变得棘手 - 是的,我已经去过地狱并在一些非常古老、非常糟糕的生产代码中看到了这一点。
如果配置之间的唯一区别是调试符号和优化,我认为没有理由不两者兼而有之。
Our policy is to have developers work on Debug builds, but EVERYONE else (QA, BAs, sales etc) runs the release version.
Yesterday I had to fix a bug that only showed up in the release build it, was obvious what was happening simply BECAUSE it only showed up in release
It's first one here in this shop, and I've been here 18 months or so.
Where things get hairy is when the Release build does different things to the debug build - Yes, I have been to Hell and seen this in some very old, very ropy production code.
I see no reason why not to have both if the only difference between the configurations are debug symbols and optimisations.
嗯...听起来你正在对我进行调试构建...对吧?
你出错的部分是这样的声明:
开发人员不测试代码。 测试代码。
您的单元测试应该测试所有构建配置。 不要让你的开发人员将一只手绑在背后工作——让他们使用他们拥有的所有调试工具。 调试版本就是其中之一。
关于断言:断言的使用很大程度上取决于您是否按契约编程。 如果这样做,则断言仅检查调试版本中的合同。
Ummm... it sounds like you're doing a debug build to me... right?
The part where you went wrong is this statement:
Developers don't test code. Tests test code.
Your unit tests should test ALL build configurations. Do not make your developers work with one hand tied behind their back - let them use all the debugging tools they have at there disposal. A Debug build is one of these.
Regarding asserts: the use of assertions greatly depends on whether or not you program by contract. If you do, then assertions merely check the contract in a debug build.
根据我在链接线程中的回答,出于非常相似的原因,我们也使用相同的构建进行调试和发布。 与算法级别的手动优化相比,优化器带来的 10%-20% 的性能提升往往非常小。 单个构建消除了许多潜在的错误。 具体来说;
未初始化的变量和小的缓冲区溢出可能会在调试和优化的发布版本中产生非常不同的结果。
未初始化的变量和小
即使有可用的符号信息,调试优化的版本也可能很困难,因为对象与源不匹配,例如变量可能已被优化并且代码可能已被重新排列。 因此,在测试的发布版本中报告的错误可能会更难以追踪,因此也更耗时。
在自动回归测试下比较了未优化和优化的构建后,优化提供的性能增益并没有提供足够的额外价值来在我的案例中拥有两个构建。 值得注意的是,我开发的软件非常消耗 CPU(例如创建和操作大型表面模型)。
As per my answer in the linked thread, we also use the same build for debug and release for very similar reasons. The 10%-20% performance gains from the optimiser tend to be very minor when compared to manual optimisations at algorithm level. A single build removes many potential bugs. Specifically;
Uninitialised variables and small buffer overflows may end up with very different results in debug and optimised release builds.
Even with the symbolic information available, debugging an optimised release can be difficult as the object doesn't match the source, e.g. variables may have been optimised out and code may have been re-arranged. Thus bugs reported in tested release builds can be more difficult, and hence time-consuming, to track down.
Having compared unoptimised and optimised builds under automated regression tests, the performance gains provided by the optimisation don't provide enough extra value to have two builds in my case. It is may be worth noting that the software that I develop is very CPU hungry (e.g. creating and manipulating large surface models).
开发人员使用调试版本,质量检查,其他人使用发布版本,我们称之为“生产”。 这样做的主要优点是,在调试构建中,我们可以添加大量额外的代码和断言。 有些对象包含额外的信息,除非在调试器中查看代码,否则这些信息没有任何用处。 某些对象会定期验证自身,以确保所有状态信息都是一致的。 这些东西使调试版本慢得多,但它们帮助我们发现了无数在生产版本中很难找到的错误。
正如我所说,我们所有的 QA 和性能测试都使用生产版本,我们偶尔会遇到在生产中出现但在调试中不会出现的问题。 但它们相对较少,并且作为开发人员,调试调试版本而不是生产版本的优势远远超过了这个问题。
Developers work with debug builds, QA and everyone else uses the release version, which we call "production". The main advantage to this is that in the debug build, we can add lots of extra code and assertions. Some objects contain extra pieces of information that have no use except when viewing code in the debugger. Some objects validate themselves periodically to make sure that all the state information is consistent. These things make the debug version much slower, but they have helped us find no end of bugs that would have been hell to find in the production build.
As I said, all of our QA and performance testing uses production builds, and we do occasionally run into problems that show up in production but not in debug. But they're relatively rare, and as a developer, the advantages of debugging a debug build rather than a production build far outweigh that problem.
当使用 Java 进行开发时,我讨厌非调试版本。 当抛出异常时,您不会获得任何行信息,这使得跟踪错误变得困难甚至不可能。 此外,对于 Java 5 或更高版本,调试和非调试之间的运行时差异约为 5%,因此这实际上不是问题,并且对于当今的硬盘,大小不再重要。
使用调试版本的好处是:
When developing with Java, I hate non-debug versions. When an exception is thrown, you get no line information which makes it hard or even impossible to track bugs down. Also, the runtime difference between debug and non-debug is around 5% with Java 5 or later, so this is really no issue and with todays hard disks, size doesn't matter anymore.
On the plus side using debug versions:
这里我们在调试模式下进行开发,并在发布模式下进行所有单元测试。 我们是一家小商店,只支持一些(12 岁以下)应用程序,范围包括经典 ASP、ASP.Net、VB.Net 和 C#。
我们还有专门的人来处理所有的测试,调试出的问题都抛回给开发人员。
here we develop in debug mode and do all unit testing in release mode. we are a small shop with just a few (under 12) application to support ranging from Classic ASP, ASP.Net, VB.Net, and C#.
We also have a dedicated person to handle all testing, debugged problems are thrown back to the developers.
我们总是同时构建两者,甚至从未考虑过不这样做。 启用调试选项会增加您的代码大小并降低性能,这可能不是测试时您的软件类型的问题,但如果客户正在运行您的代码以及 5 个其他应用程序怎么办...
测试问题可以通过使用自动化测试来解决因此,当您认为准备好发布时,可以轻松测试您的发布版本。 您的开发人员或公司未能正确测试发布版本并不是发布和调试版本理念的失败,而是您的开发人员和/或公司的失败。
关于你的最后一点,我从来没有被要求调试发布版本,只是为了修复它......
We always build both, never even considered not doing so. Enabling debug options increases your code size and slows performance, possibly not an issue with your type of software when testing but what if the customer is running your code plus 5 other apps...
The issues with testing can be sorted out by using automated testing so you're release build can be effortlessly tested when you think you're ready to release. The failure of your developers or company to properly test release builds is not a failure in the idea of release and debug builds but in your developers and or company.
On your last point, I have never been called upon to debug a release build, just to fix it...
我认为这取决于项目规模以及您使用的构建系统和测试类型。
如果您有一个自动构建系统,并且在给定构建上运行单元和功能测试很简单,那么您应该永远不会遇到多种构建类型的任何问题。
I think it depends on the project size and what type of build system and testing that you are using.
If you have an automated build system in place, and it's simple to run unit and functional tests on a given build, then you should never have any problems with multiple build types.
出于您在问题中列出的所有原因,我一直赞成“发送您调试的内容,以便您可以调试您发送的内容”方法。
I've always subscribed to the "Ship what you debug, so you can debug what you ship" approach, for all the reasons you list in your question.
在我看来,这个讨论忽略了一个非常重要的一点:
这实际上取决于它是什么类型的项目!
如果您创建本机 (C/C++) 项目,您实际上将被迫创建调试版本,仅仅是因为编译器优化在某些情况下会使调试几乎不可能。
如果您创建 Web 应用程序,您可能宁愿只拥有一个可以在运行时启用日志记录功能的构建(尽管“构建”对于某些 Web 应用程序来说相当具有误导性)。
尽管原生 C++ 项目和 PHP Web 应用程序显然不是现有的所有项目,但我希望我的观点能够得到理解。
PS:在为 C# 开发时,您会遇到边界情况,因为尽管使用调试构建会禁用编译器优化,但根据我的经验,您不会遇到与 C++ 一样多的差异
In my opinion this discussion missing a very important point:
It really depends upon what kind of project it is!
If you create a native (C/C++) project you will in effect be forced to create debug builds, simply because compiler optimizations can make debugging near impossible in some cases.
If you create web applications you might rather wish to simply have one build (although "build" is rather misleading for some web applications) that can enable logging features during runtime.
Although a native C++ project and a PHP web application are obviously not all kinds of project that exist, I hope my point got across.
P.S.: When developing for C#, you run into a border case since although using a debug build disables compiler optimizations, in my experience you will not run into nearly as much differences as with C++
这是一个权衡。 鉴于 CPU 周期很便宜并且越来越便宜,而人工周期仍然很昂贵,因此仅维护大型复杂程序的单个版本 - 调试(gable)版本是很有意义的。
始终使用断言比从不使用断言更安全。 如果生成单独的调试版本和发布版本,请重新启用您需要的任何
#define
符号,以保证在发布版本中也启用断言。It's a tradeoff. Given that CPU cycles are cheap and getting cheaper while human cycles remain expensive, it makes a lot of sense to maintain only a single version of a large, complex program -- the debug(gable) version.
Always using assertions always is a safer policy than never using them. If producing separate debug and release versions, re-enable whatever
#define
d symbols you need to guarantee that assertions are enabled in the release version also.我认为权衡很简单:是的,只需发布版本,您就可以真正测试实际发布的内容。 另一方面,您确实为开发人员的调试便利性和/或用户的性能付出了代价,因此您需要检查这两种情况。
在大多数中型到大型项目中,易于调试将确保最终为您的用户提供更好的产品。
I think the tradeoff is simple: yes, with only a release build, you really test what's actually being shipped. On the other hand, you do pay a price in ease of debugging for your developers and/or performance for the user, so it's up to you to check both cases.
On most medium- to large-size projects, ease of debugging will ensure a better product for your users in the end.
如果你有一个真正的 QA 小组,可以信赖他们来全面测试这个东西,我会说进行调试构建,直到你接近发布,然后确保在同一个构建上完成完整的 QA 周期走出门。
尽管在至少一种情况下,我们发布了一些仍然包含一些调试代码的东西。 唯一的后果是它运行得有点慢,而且日志文件非常大。
If you've got a real QA group who can be counted on to fully test the thing, I'd say make debug builds until you get close to the release, and then make sure a full QA cycle is done on the same build that's going out the door.
Although in at least one case we released something that still had some debug code in it. The only consequence was it ran a tiny bit slower and the log files were pretty damn big.
在我的公司,我们有调试和发布。
- 开发人员使用调试版本来正确查找和修复错误。
- 我们正在使用 TDD,因此我们有一个在服务器上运行的大型测试套件,用于测试调试和发布构建配置以及我们拥有的 64/32 构建。
因此,如果使用“调试”配置可以帮助开发人员更快地找到错误,则没有理由不使用它 - 当代码进入服务器(进行进一步测试)或审查时,我们使用“发布”配置。
In my company we have both Debug and Release.
- The developers use the debug version to properly find and fix bugs.
- We are using TDD and so we have a big test suite that we run on our server that tests both debug and release build configurations as well as 64/32 builds we have as well.
So if using the "debug" configuration helps a developer to find a bug faster there is no reason not to use it - when the code goes into the server (to be further tested) or reviewed we use the "Release" one.
我很久以前就学会了使用 .PDB 文件构建发布版本,以便我可以调试发布版本。 许多程序员往往忘记的是,当您运行调试版本时,所有优化都关闭,您正在调试完全不同的程序。 它的行为可能类似于发布版本(大部分),但它仍然是与发布版本不同的程序。
此外,调试发布版本并不那么困难。 如果您收到故障转储,无论如何您都必须能够做到这一点。
I learned to build the release version with .PDB files long ago so that I could debug the release version. What a lot of programmers tend to forget is that when you run the debug version, with all the optimizations turned off, you are debugging a different program altogether. It may behave like the release build (for the most part), but it is still a different program than the release build.
In addition, debugging the release build is not that difficult. And if you get a crash dump, you have to be able to do it anyway.
请参阅您最有争议的编程观点是什么?
引用:
See this What's your most controversial programming opinion?
quote:
通过删除“调试目标”,您将迫使开发人员在软件的发布版本上进行调试。 这在实践中可能意味着两件事:
1)“发布版本”将禁用优化(否则开发人员无法使用调试器)
2)任何版本都不会有特殊的 PREPROCESSOR 宏来改变其执行。
因此,您真正要做的是合并发布和调试配置,而不是仅仅消除“调试”模式。
我个人已经在 iOS 开发中做到了这一点,没有产生任何不良影响。 我们编写的代码所花费的时间不到实际发生的时间的 1%,因此优化并不是重要的贡献者。 在这种情况下,它们似乎确实导致了错误的增加,但即使没有,以一种方式进行测试,然后用不同的代码进行 QA 的想法只会引入一个需要考虑问题的因素。
另一方面,在某些情况下,优化是必要的、有用的,甚至有足够的时间来测试两者。 通常,调试和发布之间的更改非常小,根本不会给任何人造成任何问题。
By removing the "debug target", you are forcing developers to debug on the release version of the software. What that probaly means in practice is two things:
1) "release builds" will have optimizations disabled (otherwised developers can't use a debugger)
2) No builds will have special PREPROCESSOR macros altering their execution.
So what you will really be doing is merging the release and debug configurations rather than eliminating just the "debug" mode.
I personally have done this with iOS development with no ill-effects. The amount of time spent in our written code is less than 1% of what is really happening, so the optimizations were not significant contributors. In this case, they really did seem to cause an increase in bugs, but even if they didn't, the idea of testing one way, then giving to QA with different code introduces just one more factor to consider with issues.
On the other hand, there are cases where the optimizations are necessary, where they are useful, and even where there is enough time for testing both. Usually, the changes between debug and release are so minor that it doesn't cause anyone any issues at all.