我看到另一个问题的评论(我忘记了哪一个)鼓励提问者避免在调试工具中测试他/她的代码,除非有必要,引用它作为拐杖的效果。在没有“直接”证据的情况下,开发能够推断出错误原因的技能当然可以说。我自己很喜欢调试器(事实上,如果有必要,我倾向于只运行而不用),但我必须考虑每种方法的相对优点。
这些是一般性的 - 当然 - 它在语言,环境和情况方面有很大差异 - 但还有哪些其他考虑因素?
答案 0 :(得分:2)
我多次提出这个论点。调试器只是一个拐杖如果你像一个人一样使用它。我遇到了那些拒绝使用调试器的人甚至得到一段代码崩溃的堆栈跟踪,而是使用printf二分法来查找崩溃的代码行(这需要一天或更长时间......严肃的说,人们呢? )
使用调试器时可能遇到的一个问题是隧道视觉。调试器有一种方法可以将注意力集中在错误变得明显的直接区域 - 无论是崩溃,数据不正确还是其他方面 - 以牺牲可能从某些调查中受益的其他区域为代价。另一方面,实际上在调试器中执行代码执行有时可以让您从错误的方式思考代码的心理陷阱中解放出来。你可能会发誓当它实际上做Y时它会做X - 在你的眼睛有时是一个深刻的时刻之前看到它做Y.
那就是说,我只在两种情况下启动调试器:
老实说,调试器中的时间通常只有几分钟,然后就会发现问题。修复问题通常是困难的部分,而调试器对此没用。
我认为这是一个错误,而不是总是在准备好的调试器上,或者甚至在调试器下运行代码,而是运行DEBUG BUILD。你已经指出了最糟糕的问题。内存分配往往会以不同的方式发生,未初始化的数据会填充不同的值,等等。如果第一次启动发布版本是在QA获得它之前的几个星期(或者在疯狂的商店中,在您开始发货之前) ),你可能会陷入一个严重痛苦的世界。
我只见过一个只在调试版本中出现的错误。有些人认为这并不重要,因为那不是我们发货的东西,但无论如何我都调查了它,发现了一个非常糟糕的问题。
与任何工具一样,调试器具有适当且不恰当的用途。没有坏工具。
答案 1 :(得分:1)
最终,您应该使用您的代码将在野外运行的相同配置运行测试。
然后,如果测试失败,您可以退回调试模式,如果仍然失败,请将其跟踪并修复。如果它在调试模式下运行时“自我修复”,那么很高兴您现在找到它而不是发货时,并以其他方式跟踪根本原因。
答案 2 :(得分:1)
如果你有理由确定你有一些bug需要处理,那么在调试模式下运行往往会让它们更快找到它们。如果您认为错误已经消失,您希望尽可能地模拟目标环境,这通常意味着关闭调试模式。
根据您的语言,工具等,您可以做一些或多或少是两者混合的事情:生成调试信息,但其他一切如调试模式。这通常也非常有用,因此您可以按照客户看到它的方式对代码进行调试(但要注意优化会产生奇怪的现象,例如更改代码的顺序......)
答案 3 :(得分:0)
特别是在GCC中,编译器非常乐意帮助您,但老实说,问题不会经常出现。
我认为在调试模式下进行开发并没有什么问题,通常只有在你没有完全遵循语言标准时才会出现奇怪的行为(不是初始化变量等)。
准备好释放关闭调试并再次运行测试后,找到错误,冲洗并重复。我很少接触到“仅调试模式”的错误。
答案 4 :(得分:0)
我喜欢在开发期间以调试模式运行。一个很大的原因就是如此,我设置好在需要时运行调试器。
当我做更多的C ++ / MFC编程时,我会将ASSERTS放在所有位置(或跟踪,如你所描述的)并捕获许多错误并在此过程中发现许多错误的假设。
谁在乎它的运行速度有点慢?我说在调试模式下开发。当我切换到发布版本时,我很少出现错误。但是,当我即将完成时,我通常会开始运行发布版本。如果我有一些测试人员,我显然会向他们发送版本。
答案 5 :(得分:0)
我发现编写printf比python中的调试要好得多。这只是因为它更简单,你需要重新编译。在eclipse中观察变量甚至是whit pydev都是痛苦的。其中一个原因是我总是“调试”不超过几十行代码的代码。
另一方面,C中的大型项目我正在使用debuger。不同的是,在C中有指针和数组,你想要观察结构,编写简单的printf以查看序列化代码是否正常工作并不简单。
答案 6 :(得分:0)
我总是使用调试器。而且我将始终逐行单步新代码。有一整代孩子用print语句进行调试。 (特别是对于网络开发)恕我直言,这就是最先进的软件滞后的原因。
当然,您必须在调试开启和关闭时运行单元测试,但我发现与优化相关的真正编译器错误很少。