对于难以解决的错误,您的最佳做法是什么?

时间:2009-04-02 20:18:28

标签: debugging language-agnostic

我有时会发现自己试图修复一个顽固的错误,并且只是在一段时间后才发现一些非常明显的错误。

当我认为这个问题与某些事情有关时,我会发生这种情况,并且我会对其他可能出错的事情“盲目”。

大部分时间都有助于睡眠,第二天早上我立即看到问题。

过去发生在我身上的事情:

  1. 编辑没有任何效果的真实源文件的副本。
  2. 没有关注真正的问题,而是在真正的问题已经解决的同时试图解决问题。
  3. 没有进行编译/构建,因为我之前使用的是解释语言。
  4. 调试过程中你的'盲目'经历是什么?

21 个答案:

答案 0 :(得分:17)

有一件事有助于在聚焦和不注意之间找到一个良好的平衡。

  • 确保您可以在不受干扰的情况下处理错误
  • 但是如果你不能再集中注意力,也知道什么时候休息

是的,有一点可以让你睡个好觉,这是你能做的最好的事情。

最后,与同事讨论问题,通常是第二双眼睛和观点工作奇迹。令人惊讶的是,有时只是解释问题已经有所帮助,即使听众没有说什么。这称为Rubber duck debugging

答案 1 :(得分:3)

逐行使用调试器遍历代码。至少,这应该指出你不理解的东西正在发生的线。如果您最初猜测错误是什么,请停止猜测并使用调试器。

答案 2 :(得分:3)

所有好的答案。

对于非常棘手的错误,例如运行了很长时间的数值例程,并从他们过去得到的回答略有不同,有一种费力的方法通常可行。

在问题的每一边单脚,向中心工作。

喜欢获得得到正确答案的旧版本程序,而不是获得正确答案的新版本。逐步改变任何一个,使它们更紧密地联系在一起,仍然保持问题的一方,另一方面。最终,你会找到一个能带来改变的变化。

就像在调试器下运行一个较旧的程序版本,同时在调试器下运行较新的坏版本。将它们并排一步,直到它们做出不同的事情。然后重复,重新开始他们开始不同的步骤。

我发现这种双向内向工作方法适用于各种难题,而不仅仅是软件。

答案 3 :(得分:2)

如果您不想设置断点,请在任何地方打印输出。在调试时帮助我节省大量时间。然后,当然,当你看到变量输出等于你认为它应该完全不同的东西时,它就像光线一样突破。

答案 4 :(得分:2)

我发现有用的东西是要记住,在处理真正有趣/讨厌的错误时,你不必一次性地找到正确的解决方案。任何告诉你一些你还不知道的事情都代表了朝着正确方向迈出的一步,从而让你更接近答案。即使找出问题不是也有帮助,因为你知道要去其他地方看看。

怀疑这个错误可能是由条件X引起的?然后尝试拨打X到11。如果错误变得更糟(或更频繁地出现),X可能确实是你的罪魁祸首。如果没有效果,请查看其他地方。

这个bug是间歇性的吗?然后暂时忘记试图找出为什么它发生并专注于。如果你能想出一个能够可靠地再现bug的测试用例,你就可以很好地解决这个问题了。

认为代码的某个特定部分看起来很可疑?然后使用断点或打印语句(如您的环境允许的话)大量洒下它,并向自己证明它的行为正常。检查输入变量。检查输出变量。地狱,甚至可能检查环境变量。

当我难倒时,我会尝试依靠基本实验:收集数据,形成假设,检验假设,泡沫,冲洗,重复。你知道,把一些“科学”扔进我的计算机科学。 : - )

答案 5 :(得分:2)

  • 使用调试器,确保您知道“预期”行为是什么,找到“预期”行为不再发生的点
  • 如果您可以回滚到代码的工作版本并开始逐渐添加更改,则源代码控制会有所帮助,直到您发现该位破坏了该功能。
  • 使用事件日志。我最近有一个错误,它在应用程序事件日志中记录了一个DllNotFound异常。由于文件没有问题,所以没有任何意义。我花了一些时间来查看系统日志,还有一个关于缺少依赖的错误。所以使用所有可用的日志。自己将关键信息写入事件日志,并确保其按预期显示。
  • 使用google或stackoverflow进行搜索。以前其他人经历过大多数问题,你可能会对有多少人遇到同样的问题感到惊讶。
  • 开始向stackoverflow写一个问题。对于我提出的每一个问题,至少有一个或两个我没有,因为只是在写作中正确地解决了问题,这使我得到了解决方案
  • 如果可能的话,创建一个小的“一次性”空项目并尝试在那里复制问题。这可能有助于找出问题是由您的代码还是项目的其他部分引起的
  • 使用同事的帮助
  • 如果可以的话,走开一会儿,或者至少尝试做一些不同的事情。你的思想会在潜意识里继续解决这个问题,并且很快就会提供解决方案。
  • 如果没有任何帮助,请阅读文档和手册。 (:-))

一个没有任何帮助的例子:一旦我出现问题,因为我的DataGridView不会在复选框列中显示复选框。绝对没有办法实现。 我花了很长时间才发现,由于某种原因,如果列的宽度小于某个宽度,则复选框不会显示。它们在设计师中仍然可见。 (我认为原因是我们正在使用的某个UI工具包)。我不会发现,但只是偶然的鼠标移动我在运行时重新调整了一个列并且瞧 - 他们在那里,我的复选框,这一次,坐在那里看不见。

答案 6 :(得分:1)

我同意sleske,但我要补充的一件事是将工作单位分解成更小的单位。因此,如果它是方法中的错误...制作更小的方法。它将清除战争迷雾。

答案 7 :(得分:1)

使用您的版本控制系统,回到错误出现之前,并将该代码与引入错误的第一个版本区分开来。

使用二叉搜索树方法使流程更快。

我被告知有一个git命令或工具可以让这很容易。

答案 8 :(得分:1)

单独离开,并呼吁你的同事重新审视这个问题。我一次又一次地发现这种方法可以在5分钟内解决问题,而你可能会失去一整天。

答案 9 :(得分:1)

使用能够设置断点

的编辑器
  

使用Breakpoints,您无需在调试时反复开始代码的开头,这样可以更轻松地逐步执行代码

答案 10 :(得分:1)

忘记调试器。浪费时间,大部分时间。

首先,rubber duck它。如果失败,请转到计划B。

B计划:确保您有良好的单元测试。然后你可以使用诸如Kent Beck称之为“Saff squeeze”的技术来解决这个问题(假设你可以重现它)。

答案 11 :(得分:0)

在3D(游戏,例如)渲染内容中,调试始终是一场噩梦。它有时会转向像素调试器,它会在什么样的绘图调用时显示该像素被修改的颜色。

答案 12 :(得分:0)

如果您的.Net项目在Mono上失败,那么调试就是一场噩梦。大部分时间都是关于Console.WriteLine的。

有几个选择。你可以:

  • 在linux机器上调试。有单声道的命令行调试器。
  • 在linux机器上运行代码,并使用一些远程调试插件从visual studio进行远程调试(我还没有成功)
  • 在Windows上,运行MS .Net运行时,但将其与单类库链接。除了mscorelib之外你可以做到这一点,虽然它涉及到.net框架设置的一些混乱,例如禁用.net程序集的强密钥检查。

答案 13 :(得分:0)

这个问题涉及很多相同的问题:Best practices for debugging

答案 14 :(得分:0)

我很多时候都试图修复一个真正无需修复的错误。在许多情况下,用户只需要特定的行为,无论该行为是否得到保证。我遇到过这样的情况,我会花很多时间试图“修复”这个bug,只是意识到这个bug确实不是一个bug,或者修复不实用。

答案 15 :(得分:0)

就像你说的那样,最好的事情往往是从问题中退一步..也许可以在其他事情上工作一段时间,或者只是散步。

答案 16 :(得分:0)

我发现当盯着应该工作但不是的时候,我常常太努力了。抓住一个朋友并向他们解释它应该如何工作,一点一点地逐行,通常会导致问题跳出来。

答案 17 :(得分:0)

当我像我一样编程时,我必须善于发现和修复错误。 ;)

首先,我必须承认这个错误是我的。与团队合作时,很容易将其他人归咎于问题。当我得到这种倾向时,我首先要收集足够的证据来证明这些错误是他们的。大约一半的时间,我收集足够的证据来确定它是我的。到那时我正在寻找解决方案。否则,我会向另一位开发人员解释我的代码的作用,响应的内容,以及我对该响应的惊喜。这使他们更容易指出我的期望错误的地方或他们的贡献可能无法正常工作的地方。

当我确定问题是我的问题时,我会用“无情的逻辑应用”来处理它。我收集了关于不良行为的所有信息。然后我仔细检查它和代码,试图找出可能导致意外行为的原因。通常这指向可疑的代码的某些部分。此时我尝试进一步检测代码,保存变量副本或记录关键信息。根据收集的进一步信息,我评估并完善我的原始假设并继续。几次这样的迭代通常会确定错误或指向一个新的区域进行调查。我猜这归结为分析 - >仪器 - >测试 - >重复。当我发现问题时,我总是会经历至少一种仪器 - >测试迭代,以确保错误确实修复。

正如其他人所说,请求同事寻求帮助。这有两个方面的帮助。首先,在向他们解释代码时,您将更好地理解代码。即使你的同事不在你的水平,这也会有所帮助。其次,他们可能会看到你没有注意到的事情或提出没有发生的问题。

答案 18 :(得分:0)

找到了解基本问题和技术的其他人(因此他们不会给你一个空白的凝视),并向他们解释问题。他们通常甚至不需要回答,只是组织你的想法足以向其他人解释问题通常会使解决方案成为焦点。

编辑:我指的是Rubber Ducking,尽管我无法给它起个名字。谢谢Morendil

答案 19 :(得分:0)

了解您要修复的内容的价值。不要把时间浪费在“绒毛”上。如果价值低于成本,请记录,解决并继续前进。

如果价值>成本,并且你已经有了很好的解决方案,那就进行沟通吧。很多时候,由于涉及到的人的观点,一个棘手的问题只是一个棘手的问题。对其他人而言,事情往往非常明显。不要把你的团队当作拐杖,绝对要尊重他们的时间等,但同样要认识并挖掘同事和同伴的价值。

答案 20 :(得分:0)

设置一次处理任务的时间限制,例如: 2小时。一旦达到这个时间并且你没有取得进展,休息10-15分钟,可以去散步,吃点心,与人聊天,除了那个可以帮助“重置”你的精神焦点的问题过了一段时间,试图通过蛮力来解决问题是没用的。

确保您清楚地了解错误是什么。曾经有一段时间我会得到一个错误,上面写着“这看起来很丑陋。请修好”,然后想一想,“我应该把它看成是什么样的,因为我不知道怎么做这看起来不错?“有点想法。如果你不得不去找别人来指责开发人员和测试人员之间的指责,每个人都在说“我遵守规范”。裁判可以是经理,开发人员,测试人员或项目,但我确实为那些陷入这些情况的人感到难过。