处理“不可重现”错误的有效策略有哪些?

53

经常会出现一些“无法再现”的缺陷报告,这些缺陷在您的计算机或软件项目中可能是可以再现的,但在供应商的系统上却无法再现。或者用户提供了复现步骤,但您本地却看不到该缺陷。当然,这种情况有很多变化,为了简化问题,我想了解的是:

贵公司对于“无法再现”的漏洞的政策是什么?将其搁置、关闭或忽略?我偶尔会遇到第三方框架中间断、无法再现的 bug,而这些问题几乎总是被供应商立即关闭……但它们确实是真正存在的缺陷。

您是否发现任何技术可帮助解决这些类型的 bug?通常我会从用户处获取系统信息报告和复现步骤,然后搜索关键字,尝试查找任何模式。


3
这是一个非常现实的问题。仅因为开发者无法重现它并不意味着它没有发生。你不能简单地忽视它。但是,该死的问题如何确定呢? - DOK
1
社区维基?我相信这没有封闭的答案。 - Samuel Carrijo
16个回答

39
  • 核实产生错误的步骤

经常有人报告错误或重现错误时会做错一些事情,最终并未处于相同的状态,即使他们认为他们是。尝试与报告问题的一方一起分析。我曾经遇到过一个用户坚称管理员特权未正确显示。我尝试重现该错误但未能成功。当我们一起分析时,结果发现他在那种情况下登录为普通用户。

  • 核实产生错误的系统/环境

我发现很多“无法重现”的漏洞,后来才发现它们在运行Mac OS(10.4)上的Safari X版本时是可以重现的。这不仅适用于浏览器和渲染,也可能适用于任何其他正在运行的应用程序,无论用户使用RDP还是本地,以管理员身份还是普通用户身份等等……在将其视为无法重现之前,请尽可能接近他们的环境。

  • 收集截图和日志

一旦您验证了用户已经正确操作,并且仍然出现错误,并且您正在进行与他们完全相同的操作,并且您没有收到任何错误,那么现在是时候看看您实际能做什么了。截图和日志至关重要。你想确切知道它看起来像什么,以及在这个时间发生了什么。

日志可能包含一些信息,可以在您的系统上重现,一旦您可以重新生成精确的场景,您就可能能够找到错误。

截图也对此有帮助,因为您可能会发现“X块已经正确加载,但它不应该这样,因为它依赖于Y”,这可能会给您一些提示。即使用户可以描述他们正在做什么,截图也可能更有帮助。

  • 从用户那里收集逐步说明

经常会把责任归咎于用户,不相信他们说的任何话(因为他们称“用户控件”为“那个东西”),但即使他们可能不知道正在看到的事物的名称,他们仍然能够描述一些他们看到的行为。这包括可能发生在真正错误发生之前几分钟的一些小错误,或者通常很快的某些事物的缓慢。所有这些都可以作为线索帮助您缩小导致用户机器上出错的方面。

  • 尝试替代方法来复现错误

如果一切都失败了,请尝试查看导致问题的代码部分,可能需要重构或使用解决方法。如果您能够创建一个场景,在其中已经有一半的信息(希望是在UAT中),请要求用户尝试该方法,并查看是否仍然发生错误。尽力创建类似但不同的替代方法,以便更好地检查错误。


9

解决 "sterile" 和 "spooky"

我们为这种情况设立了两个关闭的错误分类。

sterile - 无法重现。

spooky - 已经确认存在问题,但它只是偶尔出现,不太容易理解,并让每个人都感到有点毛骨悚然。


9
简短回答:对疑似有问题的代码进行详细的代码审查,旨在修复任何理论上的漏洞,并添加代码以监测和记录任何未来的故障。
长篇回答: 举个嵌入式系统领域的实际例子:我们生产工业设备,其中包含定制电子设备和运行在其上的嵌入式软件。
客户报告称,单个站点上的多台设备在随机时间间隔内出现了相同的故障。它们的症状在每种情况下都是相同的,但他们无法确定明显的原因。
显然,我们的第一步是尝试在实验室中的同一设备中重现故障,但我们无法做到这一点。
因此,我们将疑似有问题的代码在部门内传阅,以获得尽可能多的想法和建议。然后我们举行了多次代码审查会议,讨论这些想法,并确定一个理论:(a)解释了在现场观察到的最可能的故障原因;(b)解释了为什么我们无法重现它;并且(c)导致我们可以改进代码以防止未来发生故障。
除了(理论上的)漏洞修复外,我们还添加了监测和记录代码,因此如果故障再次发生,我们可以从相关设备中提取有用的数据。
据我所知,这种改进的软件随后部署在现场,并且似乎很成功。

8

错误报告、日志文件以及严厉要求“如果再次发生,请立即联系我”的要求。


8
如果在一个环境中发生了某些事情而在另一个环境中没有发生,我们会尝试列举两者之间的差异并消除它们。有时候这种方法是有效的(例如其他硬件、双核与超线程、笔记本电脑硬盘与工作站硬盘等)。但有时候不行。如果可能的话,我们可能会开始远程调试。如果这也无济于事,我们可能会尝试获取客户系统的实际操作体验。当然,我们首先不会写太多的错误 :)

是的,获取用户的物理硬件信息... 这对我帮助很大,我忘了提到这一点... - P a u l

2

好的,您尽力去复制它,如果您不能复制,您需要认真思考并考虑这样的问题可能如何产生。如果您仍然没有头绪,那么您就无能为力了。


1
当你的工作是修复错误时,不幸的是说“我能做的不多”是行不通的。 - DevinB
2
如果它是真的,那么它就是真的。 - John Saunders

2
有时候即使在完全复制生产环境的预生产环境中,错误也无法再现。并发问题以此而闻名。
随机故障通常是并发问题。
链接:https://pragprog.com/tips/ 原因可能很简单,因为海森堡效应,即观察会改变行为。另一个原因可能是击中触发错误的事件组合的概率非常小。
有时候你很幸运,有审计日志可以播放,大大增加了重新创建问题的机会。您还可以使用大量交易来压力环境。这有效地压缩时间,因此如果错误每周发生一次,则如果将系统压力提高到7倍生产负载,您可能能够可靠地再现它1天。
最后的办法是白盒测试,在其中逐行查看代码并编写单元测试。


1
重要的是将这类错误(很少能重现)进行分类,并针对性地采取不同于频繁出现的、基于特定用户操作的错误的处理方式。
  1. 清晰的问题描述以及重现步骤和观察到的行为:明确的报告有助于整个团队理解问题,消除不正确的结论。例如,用户报告空白屏幕与用户操作时HMI冻结是不同的。步骤顺序和用户操作的大致时间也很重要。用户在屏幕转换后立即选择选项还是等了几分钟?一个有趣的关于时间的错误是一辆对香草冰淇淋过敏的汽车,使汽车工程师感到困惑。

  2. 系统配置和启动参数:有时甚至硬件配置和应用软件版本(包括驱动程序和固件版本)可能会起作用。 版本或配置不匹配可能导致其他设置中难以重现的问题。 因此,这些是必须捕获的关键细节。 大多数错误报告工具在记录问题时都将这些详细信息作为强制性参数。

  3. 广泛的日志记录:这取决于涉及项目中遵循的日志记录设施。 在使用嵌入式Linux系统时,我们不仅提供一般诊断日志,还提供系统级别日志,例如dmesg或top命令日志。 您可能永远不知道错误的部分不是代码流而是异常内存使用/ CPU使用。 确定问题类型并报告相关日志以进行调查。

  4. 代码审查和演练:开发团队不能永远等待在其端复制这些问题,然后采取行动。 应根据设计和代码从错误报告和可用日志中进行调查并识别各种可能性。 如果需要,他们应该准备针对可能的根本原因的热修补程序,并将热修补程序传递给包括发现它的测试人员在内的团队,以查看是否可以使用它来重现错误。

  5. 不要根据单个测试人员/团队的观察结果在修复后关闭这些问题:也许最重要的部分是关闭这些问题所遵循的方法。 一旦解决这些问题的方法已经检查过,就应通知不同位置的所有测试/验证团队进行深入测试,并在必要时识别回归错误。 只有当所有(实际上大多数)团队都报告不可再现时,高级管理层才能进行关闭评估。


1

我在整个程序中添加了异常处理代码的日志记录。您需要一种方法来收集日志(用户可以通过电子邮件发送等方式)。

对代码版本和合理环境进行预防性检查也是一件好事。随着现今软件更新的便利,用户运行的代码和环境几乎肯定没有经过测试。这些都是在您发布代码时不存在的。


是的。我不明白为什么微软没有创建一个 .net API 来获取框架版本。我们只能使用各种临时解决方案来解决这个问题。这是我绝对需要让它工作的东西。 - P a u l

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接