![]() |
1
27
成对分析问题,成对读取代码。记下你知道是真的问题,试着确定哪些逻辑前提 必须 为这件事坚持到底。像CSI一样跟踪证据。 大多数人本能地说“添加更多日志”,这可能是一个解决方案。但对于许多问题,这只会使情况变得更糟,因为日志记录可以充分改变时间依赖性,从而使问题或多或少地更频繁。将频率从1000中的1更改为1000000中的1不会使您更接近问题的真正根源。 因此,如果您的逻辑推理不能解决问题,它可能会给您一些您可以在代码中使用日志或断言进行调查的细节。 |
![]() |
2
25
添加某种日志记录或跟踪。例如,记录用户在导致错误之前提交的最后X个操作(仅当您可以设置与错误匹配的条件时)。 |
![]() |
3
21
这个问题没有一般的好答案,但我发现:
如果您没有假设,这通常是由于系统知识不足(即使您自己编写了每一行代码也是如此),您需要运行和检查代码,并获得对系统的更多洞察,以提出一个新的想法。 当然,上面的任何一项都不能保证任何东西,但我发现这是一种始终如一地获得结果的方法。 |
![]() |
4
8
对于程序员来说,不能够简单地重复用户经历过的崩溃是很常见的,因为您在使用明显绕过错误的应用程序时开发了特定的工作流和习惯。 在这个1/100的频率下,我想说的第一件事就是处理异常并在任何地方记录任何东西,或者您可能要花一周时间来搜索这个bug。 还可以列出项目中可能敏感的发音和特性的优先列表。例如: 1-多线程 2-野生指针/松散数组 3-依赖输入设备 等。 这将有助于你分割那些你可以强暴的区域,直到像其他海报建议的那样再次被打破。 |
![]() |
5
7
因为这是语言不可知论,所以我将提到一些调试的公理。 计算机所做的一切都不是随机的。“随机事件”表示尚未发现的模式。调试从隔离模式开始。改变单个元素并评估是什么导致了错误行为的改变。 不同的用户,相同的计算机? 相同的用户,不同的计算机? 这种现象是周期性的吗?重启会改变周期吗? 仅供参考-我曾经看到一个由一个人经历的错误。我的字面意思是人,而不是用户帐户。用户A不会看到他们系统上的问题,用户B会坐在工作站上, 以用户A身份登录 并且可以立即复制这个错误。应用程序不应该有任何可以想象的方法来了解椅子中身体的区别。但是- 用户以不同的方式使用该应用程序。用户A习惯使用热键调用操作,用户B使用屏幕控件。用户行为的差异会在稍后的几次操作中级联为可见的错误。 任何影响bug行为的差异都应该被调查,即使它毫无意义。 |
![]() |
6
5
您的应用程序很有可能是mtwidntbmt(当它不需要多线程时是多线程的),或者只是多线程(礼貌地说)。在多线程应用程序中重现零星错误的一个好方法是像这样散布代码(c):
和/或此:
模拟线程在不同的时间完成其任务,或者长时间地捆绑处理器。 这些年来,我继承了许多有缺陷的多线程应用程序,像上面的例子一样的代码通常会使零星的错误发生得更频繁。 |
![]() |
7
4
添加详细日志记录。需要多次(有时是十几次)迭代才能添加足够的日志来理解场景。 现在的问题是,如果问题是一个争用条件,如果它不能可靠地重现,那么日志记录可以改变时间,问题将停止发生。在这种情况下,不要将日志记录到文件中,而是将日志的旋转缓冲区保留在内存中,并且仅在检测到问题发生时将其转储到磁盘上。 编辑:还有一点想法:如果这是一个GUI应用程序,用一个允许您重放宏的QA自动化工具运行测试。如果这是一个服务类型的应用程序,那么至少要对正在发生的事情进行猜测,然后以编程的方式创建“异常”的使用模式,使用您怀疑的代码。创造比通常更高的负荷等。 |
![]() |
8
3
什么开发环境? 对于C++,你最好的赌注是VMware工作站记录/重放,请参阅: http://stackframe.blogspot.com/2007/04/workstation-60-and-death-of.html 其他建议包括检查堆栈跟踪和仔细的代码概述…真的没有银弹:) |
![]() |
9
2
尝试在应用程序中添加代码,以便在错误发生时自动跟踪它(或者甚至通过邮件/短信提醒您)。 记录你能记录的任何东西,这样当它发生时,你就能捕捉到正确的系统状态。 另一件事-尝试应用自动化测试,它可以以一种成形的方式覆盖比基于人的测试更广的领域。这是一个长期的尝试,但一般来说是一个很好的实践。 |
![]() |
10
2
所有这些,再加上一些半随机的强力机器人,并通过代码分散大量的断言/验证(C/C++,可能类似于其他的Langs)。 |
![]() |
11
2
大量的日志记录和仔细的代码审查是您唯一的选择。 如果部署了应用程序,并且您无法调整日志记录,那么这些操作会特别痛苦。在这一点上,你唯一的选择就是用一把细齿梳子仔细检查代码,并试图解释程序如何进入不良状态(科学的拯救方法!) |
![]() |
12
2
通常,这些类型的错误与损坏的内存有关,因此它们可能不会经常出现。您应该尝试使用某种类型的内存分析器(如Valgrind)运行您的软件,以查看是否出了问题。 |
![]() |
13
2
让我们假设我从生产应用程序开始。
|
![]() |
14
2
单元测试。在应用程序中测试一个bug通常是可怕的,因为有太多的噪音,太多的可变因素。一般来说,干草堆越大,就越难确定问题所在。创造性地扩展单元测试框架以支持边缘案例可以节省数小时甚至数天的筛选时间。 说了没有银弹。我感觉到你的痛苦。 |
![]() |
15
2
添加与此Bug相关的前置和后置条件签入方法。 你可以看看 Design by contract |
![]() |
16
2
除了耐心之外,你还需要安静的祈祷和诅咒:
Hth. |
![]() |
17
2
假设你在Windows上,而你的“bug”是一个崩溃或某种非托管代码(C/C++)中的腐败,那么看看 Application Verifier 来自Microsoft。该工具有许多停止功能,可以在运行时验证内容。如果您知道发生错误的场景,那么尝试运行AppVerifer运行的场景(或场景的压力版本)。确保在appverifier中打开pageheap,或者考虑使用/rtccsu开关编译代码(请参见 http://msdn.microsoft.com/en-us/library/8wtf2dfz.aspx 更多信息)。 |
![]() |
18
1
“ Heisenbugs “需要很好的诊断技能,如果你想得到这里的人的帮助,你必须更详细地描述这一点,耐心地听各种测试和检查,在这里报告结果,并反复进行直到你解决它(或认为它在资源方面太贵)。 您可能需要告诉我们您的实际情况、语言、数据库、操作系统、工作量估计、过去发生的一天中的时间,以及许多其他事情,列出您已经做过的测试,它们是如何进行的,并准备做更多的工作并分享结果。 这也不能保证我们共同能找到它… |
![]() |
19
1
我建议写下用户所做的一切。如果你有10个这样的bug报告,你可以试着找到连接它们的东西。 |
![]() |
20
1
仔细阅读堆栈跟踪并尝试猜测可能发生的情况; 然后尝试跟踪\记录可能导致问题的每一行代码。 把你的注意力集中在处理资源上;我发现的许多小的零星的bug都与close\dispose things:有关。 |
![]() |
21
1
对于.NET项目,您可以使用elmah(错误日志模块和处理程序)来监视应用程序是否存在未捕获的异常,安装非常简单,并且提供了一个非常好的界面来浏览未知错误。 http://code.google.com/p/elmah/ 这使我今天能够捕捉到在注册过程中发生的一个非常随机的错误。 除此之外,我只能建议您尽可能多地从您的用户那里获取信息,并对项目工作流程有一个透彻的了解。
|
![]() |
22
1
我与之合作的团队已经邀请用户记录他们在CamStudio应用程序中花费的时间,当我们有一个令人讨厌的bug需要跟踪时。它很容易安装和使用,并且使复制那些烦人的bug更加容易,因为您可以观察用户在做什么。它也与您使用的语言没有关系,因为它只是在录制Windows桌面。 然而,只有当你在开发公司应用程序并与你的用户建立良好的关系时,这种方法才是可行的。 |
![]() |
23
1
这是不同的(如你所说),但一些方便的东西可以
|
![]() |
24
1
@P.Marino-没有足够的代表发表评论=/ tl;dr-由于一天中的某个时间而导致的构建失败 你提到了一天中的时间,这引起了我的注意。曾经有一个bug,就是有人在晚上工作到很晚,试图在离开前建立并提交,结果一直失败。他们最终放弃了,回家了。当他们第二天早上发现它建造得很好时,他们承诺(可能应该更可疑)建造对每个人都有效。一两周后,有人迟到了,并发生了意外的构建失败。结果发现代码中有一个bug,它在7pm中断后生成了任何版本>> 今年1月,我们在项目中一个很少使用的角落发现了一个错误,它导致了不同模式之间的编组问题,因为我们没有考虑到基于0和1个月的不同日历。因此,如果没有人搞乱项目的那一部分,我们就不可能在2011年1月之前找到这个bug。 这些问题比线程问题更容易解决,但我认为仍然很有趣。 |
![]() |
25
1
雇佣一些测试人员! |
![]() |
26
1
这对非常奇怪的海森氏菌很有效。 (我还建议获取一份戴夫·阿甘的“调试”副本,这些想法部分来自于使用他的想法!) (0)使用memtest86之类的工具检查系统的RAM! 整个系统展示了问题所在,所以做一个测试夹具来练习整个系统。 假设这是一个服务器端的图形用户界面,你运行整个图形用户界面测试框架做必要的输入来引发问题。 它不会100%失败,所以你必须让它更经常失败。 先把系统切成两半(二进制斩波) 更糟的是,您必须一次删除一个子系统。 如果他们不能被评论掉,就把他们赶走。 看看它是否仍然失败。失败的频率更高吗? 保持正确的测试记录,一次只更改一个变量! 最坏的情况是,你使用夹具,你测试了几个星期,以获得有意义的统计数据。这很难,但请记住,夹具正在做这项工作。 我没有线程,只有一个进程,而且不与硬件通信 如果系统没有线程,没有通信进程,没有接触硬件;这很棘手;heisenbugs通常是同步的,但是在没有线程没有进程的情况下,它更可能是未初始化的数据,或者在释放后使用的数据,无论是在堆上还是在堆栈上。尝试使用像valgrind这样的检查器。 对于线程/多进程问题: 尝试在不同数量的CPU上运行它。如果它在1上运行,请尝试在4上运行!尝试将4计算机系统强制为1。 它主要是确保事情一次发生一件。 如果有线程或通信进程,这可以消除错误。 如果这没有帮助,但您怀疑它是同步或线程,请尝试更改操作系统时间片大小。 尽你的操作系统供应商所能做到最好! 有时这使得比赛条件几乎每次都发生! 显然,试着在时间上放慢速度。 然后,设置测试夹具运行,并在各处附加调试程序,等待测试夹具在出现故障时停止运行。 如果其他的都失败了,把硬件放进冷冻室,然后在那里运行。所有事情的时机都会改变。 |
![]() |
27
1
调试既困难又耗时,特别是如果您无法确定地重现问题。我给你的建议是找出决定性地复制它的步骤(不仅仅是有时)。 近几年来,在失败再现领域有了大量的研究,并且仍然非常活跃。迄今为止,记录与回放技术一直是大多数研究者的研究方向。这就是你需要做的: 1)分析源代码并确定应用程序中不确定性的来源,也就是说,可以通过不同的执行路径(例如用户输入、操作系统信号)将应用程序带到哪些方面。 2)下次执行应用程序时将它们记录在日志中 3)当您的应用程序再次失败时,您可以在日志中复制失败的步骤。 如果您的日志仍然不能重现失败,那么您将处理并发性错误。在这种情况下,您应该看看应用程序如何访问共享变量。不要试图记录对共享变量的访问,因为您会记录太多的数据,从而导致严重的慢行和大量的日志。不幸的是,我不能说有太多东西可以帮助您重现并发性错误,因为在这个主题中,研究还有很长的路要走。我能做的最好的事情是提供一个参考,参考最近(到目前为止)关于并发错误确定性重播的主题: http://www.gsd.inesc-id.pt/~nmachado/software/Symbiosis_Tutorial.html 顺祝商祺! |
![]() |
28
0
使用增强的崩溃报告程序。在Delphi环境中,我们有Eurekalog和Madexcept。其他工具存在于其他环境中。或者您可以诊断核心转储。您正在寻找堆栈跟踪,它将向您显示它在哪里爆炸,它是如何到达那里的,内存中有什么等等。如果它是一个用户交互的东西,那么有一个应用程序的屏幕截图也是很有用的。以及关于它崩溃的机器的信息(操作系统版本和补丁,当时还运行什么,等等),我提到的两个工具都可以做到这一点。 如果是一些用户发生的事情,但是你不能复制它,他们可以,和他们坐在一起看。如果不明显,换个座位——你“开车”,他们会告诉你该怎么做。您将以这种方式发现微妙的可用性问题。双击一个单击按钮,例如,在on click事件中启动重新进入。那种事。如果用户是远程的,使用webex、wink等来记录他们崩溃的情况,这样您就可以分析播放了。 |
![]() |
Abdullah Chaudhry · json文件上的文件旋转和删除 2 年前 |
![]() |
Max S · 如何从CMD读取日志的所有输出 7 年前 |
![]() |
Ivan Denchev · Apache-过去一小时的日志 7 年前 |
![]() |
ninja.coder · Log4j中的字符串串联性能 7 年前 |
![]() |
Rich · 如何记录日志。是否与操作员一起调试? 7 年前 |