什么有助于您提高找到错误的能力?

时间:2009-02-22 16:45:46

标签: debugging

我想知道是否有方法可以快速找到程序中的错误。

似乎掌握软件架构越多,速度就越快 你可以找到错误。

程序员如何提高查找错误的能力?

20 个答案:

答案 0 :(得分:8)

记录和单元测试。关于发生的事情的信息越多,重现它就越容易。您可以使代码越模块化,就越容易检查它是否 在您认为的地方行为不端,然后检查您的修复是否解决了问题。

答案 1 :(得分:6)

分而治之。无论何时进行调试,都应该考虑减少问题的可能位置。每次运行应用程序时,您都应该尝试消除可能的来源并将实际位置归零。这可以通过日志记录,调试器,断言等来完成。

答案 2 :(得分:5)

在您发现错误之后,这是一种预防方法:我发现花一点时间思考这个错误确实很有帮助。

  1. 本质上究竟是什么错误。
  2. 为什么会这样。
  3. 你能早点找到它,更容易。
  4. 你从臭虫那里学到的任何其他东西。
  5. 我发现花一点时间思考这些事情会使你将来不太可能产生同样的错误。

答案 3 :(得分:3)

我会假设你的意思是逻辑错误。我发现捕获逻辑错误的最好方法是实现某种测试方案。查看jUnit作为标准。几乎你定义了一组接受的方法输出。每次编译系统时,它都会检查所有测试用例。如果您引入了破坏测试的新逻辑,您将立即了解它并确切知道您需要修复的内容。

测试驱动设计现在是一个非常大的编程运动。你很难找到一种不支持某种测试的语言。即便是JavaScript也有很多测试套件。

答案 4 :(得分:3)

经验使您成为更好的调试器。密切关注你和其他人通常犯的错误。试着弄清楚这些错误是否/如何适用于影响你的所有代码,而不是单独查看错误的位置。

Raymond Chen因其psychic debugging的力量而闻名。

  

大多数看似精神的东西   调试真的只是知道什么   人们往往会出错。

这意味着您不一定非常熟悉架构/系统。您只需要足够的知识来理解适用的错误类型,并且很容易实现。

答案 5 :(得分:2)

我个人采用的方法是在实际打开代码并查看之前考虑代码中的错误。当您第一次开始使用这种方法时,它实际上可能无法正常工作,特别是如果您对代码库非常不熟悉。但是,随着时间的推移,有人能够告诉您他们遇到的行为,并且您可以很好地了解问题的位置,或者您甚至可以知道在代码中修复问题,以便在查看代码之前解决问题

我在一个项目上工作了几年,由供应商维护。它们不是很好的调试器,大部分时间我们都要将它们指向存在问题的代码区域。让我们的问题变得更糟的是我们没有很好的方法来查看源代码,所以很多我们的“调试”只是感觉。

答案 6 :(得分:2)

错误检查和报告。 #1新手编码器调试错误是关闭错误报告,避免检查是否有意义,等等。一般来说,人们觉得如果他们看不到任何错误,那么什么都不会出错。当然,这种情况无法进一步发展。

相反,你的代码应该充满了会产生大量噪音的错误条件,通过详细的报告,你会看到它。 (这并不意味着在生产网页中。)然后,不是必须在整个地方追踪错误,因为它在最终到达某个地方之前已经通过了16层执行,你的错误开始发生在接近实际问题。

答案 7 :(得分:2)

睡觉和休息。

答案 8 :(得分:2)

  

看来你掌握得越多   你的软件架构   你可以更快地找到错误。

在理解了架构后,人们发现应用程序中的错误的能力随着识别和编写大量测试的能力而提高。

答案 9 :(得分:2)

了解您的工具。

确保您知道如何在调试器中使用条件断点和监视。

使用静态分析工具 - 他们可以指出更明显的问题。

答案 10 :(得分:1)

  • 使用首先产生较少错误的编程方法。

如果要实现单个独立的功能需求,需要对源代码进行N次单独的点编辑,放入代码的错误数量大致与N成比例,因此找到最小化N的编程方法。 :DRY(不要重复自己),代码生成和DSL(特定于域的语言)。

  • 如果可能存在错误,请进行单元测试。

显然。
恕我直言,最好的单元测试是monte-carlo。

  • 使中间结果可见。

例如,编译器具有4元组形式的中间表示。如果有错误,可以检查中间代码。这表明错误是在编译器的第一部分还是后半部分。

P.S。大多数程序员都不知道他们可以选择使用多少数据结构。您使用的数据结构越少,由此引起的错误(和性能问题)的可能性就越小。

答案 11 :(得分:1)

我发现tracepoints是一个非常宝贵的调试工具。它们有点像日志记录,除非您在调试会话期间创建它们以解决特定问题,例如断点。

在跟踪点中打印堆栈跟踪特别有用。例如,您可以在对象的构造函数中打印哈希代码和堆栈跟踪,然后在再次使用该对象时,您可以搜索其哈希码以查看创建它的客户端代码。同样是看谁处理它或称某种方法等。

它们也非常适合调试与窗口焦点更改等相关的问题,如果您在中断模式下,调试器会发生干扰。

答案 12 :(得分:1)

FindBugs

等静态代码工具

答案 13 :(得分:1)

断言,断言和断言。

我们代码的某些区域对每行实际代码都有4或5个断言。当我们得到错误报告时,首先发生的事情是客户数据在我们的调试版本中被处理99次,一百次断言将触发错误原因附近。

此外,我们的调试版本执行冗余计算以确保优化算法返回正确的结果,并且还使用调试函数来检查数据结构的完整性。

新开发人员必须应对的最难的事情是让他们的代码能够在gthey调用的代码断言中存活下来。

此外,我们不允许任何代码被放回到顶层,导致任何集成或单元测试失败。

答案 14 :(得分:0)

Scientific debugging是我一直使用的,它非常有帮助。

基本上,如果您可以复制错误,则可以跟踪其来源。然后,您应该尝试一些测试,观察结果,并推断出错误发生原因的假设。

写下您的所有假设,尝试,预期结果和观察到的结果可以帮助您追踪错误,特别是如果他们感到讨厌。

有一些自动化工具可以帮助您完成该过程,尤其是git-bisect(以及其他修订系统上的类似bisection工具),以快速找到哪些更改引入了错误unit testing重现错误并防止代码中出现回归(可以与bisect一起使用),delta debugging找到代码中的罪魁祸首(类似于git-bisect,但git-bisect适用于代码历史,delta调试直接在代码上工作。)

但无论您使用哪种工具,最重要的好处都在于科学方法,因为这是最有经验的调试器的形式化。

答案 15 :(得分:0)

我是QA团队工作的一部分,了解产品及其开发方式,帮助大量查找错误,同时当我制作新的QA工具时,我通过它对我们的开发团队进行测试,在你自己的代码中找到bug只是简单的 hard

有些人说程序员被污染,所以我们看不到他们自己产品中的错误;我们不是在谈论代码,我们超越了它,可用性和功能本身。

同时单元测试接缝是一个很好的解决方案,可以在你自己的代码中找到bug,如果你在编写单元测试之前就错了就完全没有意义,你怎么会找到bug呢?你没有!,让你的同事找到他们,聘请一个QA人。

答案 16 :(得分:0)

如果你认为操作系统中一定存在错误,请检查你的断言 - 并使用“assert”语句将它们放入代码中。

相反,在编写代码时,请考虑算法的有效输入范围,并插入断言以确保您拥有自己的想法。输出也是如此:检查您是否生产了您认为自己生产的产品。

E.g。如果你期望一个非空列表:

l = getList(input)
assert l, "List was empty for input: %s" % str(input)

答案 17 :(得分:0)

软件中的“架构”意味着:

  • 几个组件
  • 组件在明确定义的界面上进行交互
  • 每个组件都有明确的责任
  • 一个组件的责任与其他组件的责任不同

所以,正如你所说,架构越好,就越容易发现错误。

首先:了解错误,您可以决定哪些功能被破坏,因此知道哪个组件实现了该功能。例如,如果错误是没有正确记录某些内容,那么这个错误应该在3个地方之一:

  1. 在负责记录的组件(您的日志记录库)
  2. 或者,在使用此库的应用程序代码中
  3. 之上
  4. 或者,低于此库使用的系统代码
  5. 第二:检查跨组件之间的接口传输的数据。继续上面的例子:

    • 在调用记录器API的应用程序代码上设置调试器断点,以验证记录器API是否正确使用(例如,是否正在调用它,参数是否符合预期等)。
    • 这样做会告诉您错误是在此界面上方的组件中,还是在此界面下方的组件中。
    • 重复(如果调用堆栈非常深,可能使用二进制搜索),直到找到哪个组件出错为止。

答案 18 :(得分:0)

在代码中编写Debug.Write(message)并使用DebugView是另一种选择。然后运行您的应用程序,了解正在发生的事情。

答案 19 :(得分:0)

单步执行代码,检查发生意外行为的流/状态。 (当然,为它开发一个测试)。