任何处理“不可重现”错误的好策略?

很多时候,你会得到或提交“不可重现”缺陷的错误报告。 它们可能在您的计算机或软件项目上可重现,但不能在供应商的系统上重现。 或者用户提供重现的步骤,但在本地不能看到缺陷。 这个场景当然有很多变化,所以为了简化,我想我正在学习的是:

贵公司对“不可重现”错误的政策是什么? 搁置他们,closures他们,忽略? 我偶尔会在第三方的框架中看到间歇性的,不可重复的错误,而这些几乎总是由供应商立即closures……但它们是真正的错误。

你有没有find任何技术来帮助解决这些types的错误? 通常,我所做的是从用户那里获取系统信息报告,然后重新生成步骤,然后search关键字,并尝试查看任何types的模式。

  • validation用于产生错误的步骤

通常情况下,报告错误的人或者错误的人会做错事,而不会以相同的状态结束,即使他们认为自己是错误的。 尝试与报告方一起阅读。 我有一个用户INSIST,pipe理员权限显示不正确。 我试图重现错误,无法。 当我们一起走过去的时候,事实certificate他是以常规用户的身份login的。

  • validation用于产生错误的系统/环境

我发现了许多“无法复制”的错误,后来才发现它们可以在Mac OS(10.4)上运行X版本的Safari。 这不仅适用于浏览器和渲染,它可以适用于任何东西; 当前正在运行的其他应用程序,无论用户是RDP还是本地用户,pipe理员或用户等等……确保您在使其无法复制之前,尽可能地让自己的环境尽可能靠近他们的环境。

  • 收集截图和日志

一旦你确认了用户正在做的一切正确,仍然有一个错误,并且你正在做他们正在做的事情,而你没有得到错误,那么现在是时候看看你实际上可以做些什么。 截图和日志是至关重要的。 你想知道到底是什么样的,到底是怎么回事。

日志可能包含一些可以在系统上重现的信息,一旦您可以重现确切的场景,就可以瞒过隐藏的错误。

截图也有助于这个,因为你可能会发现“X块已经正确加载,但它不应该有,因为它是依赖于Y”,这可能会给你一个提示。 即使用户可以描述正在做什么,屏幕截图可以帮助更多。

  • 收集用户的分步说明

指责用户是非常常见的,不要相信他们所说的任何东西(因为他们称之为“用户控制”),但即使他们可能不知道他们所看到的名字,他们仍然可以描述他们所看到的一些行为。 这包括在真正的错误发生之前可能发生的几分钟的一些小错误,或者在某些通常很快的事情中可能缓慢的错误。 所有这些都可以帮助你缩小哪些方面是造成他们的机器上的错误,而不是你的。

  • 尝试替代方法来产生错误

如果一切都失败,请尝试查看导致问题的代码部分,并可能重构或使用解决方法。 如果您可以创build一个场景,那么您已经有一半的信息(希望在UAT中),请用户尝试这种方法,并查看错误是否仍然存在。 你最好是创build一个交替但类似的方法,使错误变成不同的光线,以便更好地检查它。

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

如果发生在一种情况下,而不是在另一种情况下,我们试图列举两者之间的差异,并消除它们。

有时候,这可以工作(例如,其他硬件,双核与超线程,笔记本电脑与工作站磁盘,…)。

有时候不会。 如果可能的话,我们可以开始远程debugging。 如果这样做没有帮助,我们可以试着抓住客户的系统。

但是,当然,我们不写太多的错误在第一位:)

解决了“不育”和“诡异”

对于这种情况,我们有两个closures的bug类别。

无菌 – 不能繁殖。

令人毛骨悚然的 – 人们承认有一个问题,但它只是间歇性地出现,不是很容易理解,并给每个人一个微不足道的小毛病。

简答:对可疑的错误代码进行详细的代码审查,目的是修复任何理论上的错误,并添加代码来监视和logging将来的错误。

漫长的回答:为了给出embedded式系统世界的一个真实的例子:我们制造包含定制电子的工业设备,以及运行在其上的embedded式软件。

一位客户报告说,单个站点上的多台设备随机出现同样的故障。 他们的症状在每种情况下都是一样的,但是他们不能确定一个明显的原因。

显然,我们的第一步是在实验室的同一设备上尝试重现故障,但是我们无法做到这一点。

因此,我们在部门内部散发了可疑的错误代码,试图获得尽可能多的想法和build议。 然后,我们举行了一些代码审查会议来讨论这些想法,并确定了一个理论:(a)解释在该领域观察到的缺陷的最可能原因; (b)解释了为什么我们无法复制它; (c)导致我们可以对代码进行改进,以防止将来发生故障。

除了(理论上的)错误修复之外,我们还增加了监视和日志代码,所以如果错误再次发生,我们可以从有问题的设备中提取有用的数据。

据我所知,这个改进后的软件随后在现场部署,似乎已经成功。

那么,你尽可能地重现它,如果你不能,那么你需要长时间思考,并考虑可能会出现这样一个问题。 如果你还不知道,那么你可以做的事情就不多了。

Visual Studio 2010中的一些新function将有所帮助。 看到:

  • Visual Studio Team System 2010中的历史debugging器和testing影响分析
  • 使用Visual Studio Team System 2010提高软件质量
  • 使用Visual Studio Team System 2010进行手动testing

我在整个程序中将日志logging添加到exception处理代码中。 您需要一种收集日志的方法(用户可以通过电子邮件等方式)

抢先检查代码版本和理智的环境也是一件好事。 现在,随着软件更新的方便,用户运行的代码和环境几乎肯定没有经过testing。 当你释放你的代码时,它不存在。

在我正在开发的一个Web项目中,我正在做一些与您的技术非常相似的事情。 我正在构build一个页面,可以引导用户收集信息,例如浏览器版本和操作系统。 我也将收集应用程序registry信息,所以我可以看看他们一直在做什么。

这是一个非常现实的问题。 我只能说Web开发,但是我发现用户很less能够给我提供我需要查看的基本信息。 我怀疑完全可以做一些类似于其他types的开发。 我的计划是继续在这个系统上工作,使它变得越来越有用。

但是我的政策决不会仅仅因为我不能复制它,而不pipe它有多烦人。 然后就是这种情况,当它不是一个错误,但用户只是变得困惑。 我猜测这是一种不同types的错误,但同样重要。

你谈论可重现的问题,但只能在一些系统上。 这些很容易处理:

第一步:通过使用某种远程软件,让客户告诉您如何在系统上重现问题。 如果失败,则closures它。

第二步:尝试在另一个系统上重现问题。 如果失败,请准确复制客户系统。

第三步:如果仍然失败,则无法尝试在客户系统上进行debugging。

一旦你可以重现它,你可以修复它。 在什么系统上无关紧要。

棘手的问题是真正的不可重复的问题,这只是间歇性的事情。 为此,我将不得不与报告,日志和严厉的要求态度相吻合。 🙂

有时候,即使在与生产环境完全相同的预生产环境中,该错误也是不可重现的。 并发问题是这个臭名昭着的。

原因可能仅仅是因为海森堡效应,即观察变化的行为。 另一个原因可能是因为触发错误的事件组合的机会很小。

有时候你很幸运,你有审计日志,你可以回放,大大增加了重现问题的机会。 您还可以通过大量交易来强调环境。 这有效地压缩了时间,以便如果每周发生一次错误,如果您将系统强调为生产负载的7倍,则可以在1天内可靠地重现该错误。

最后的手段是白盒testing,你通过线编写unit testing的代码行,你去。

伐木是你的朋友!

一般来说,当我们发现一个我们无法复制的bug时,会发生什么情况,我们要么让客户打开更多的日志logging(如果可用的话),要么在我们感兴趣的区域附近添加额外的日志logging版本。我们拥有的日志loggingfunction非常好,而且能够非常详细,所以发布带有额外日志logging的版本不会经常发生。

你也应该考虑使用内存转储(其中IMO也属于日志logging)。 生产一个小型转储非常快,通常可以在生产服务器上完成,即使在负载下(只要生产的转储数量很less)。

我看到它的方式:能够重现问题是很好的,因为它给了你一个可以更自由地进行debugging,体验和游戏的环境,但是 – 重现错误并不是debugging它的必要条件 ! 如果这个错误只发生在别人的系统上,那么你仍然需要用同样的方法来诊断和debugging这个问题,只是这次你需要更清楚自己是如何做到的。

对这些错误进行分类是非常重要的(很less重现),并根据特定的用户操作对这些错误进行不同的处理。

  1. 明确问题描述以及重现和观察行为的步骤 :明确的报告有助于整个团队了解问题,消除不正确的结论。 例如,用户报告黑屏与用户操作中的HMI冻结不同。 用户操作的步骤顺序和时间也很重要。用户在屏幕过渡后立即select选项还是等待几分钟? 关于时机的一个有趣的错误是对汽车工程师感到困惑的对香草冰淇淋过敏的汽车。

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

  3. 广泛的日志logging :这取决于相关项目中的日志logging设施。 在使用embedded式Linux系统时,我们不仅提供一般的诊断日志,还提供系统级日志,如dmesg或top命令日志。 您可能永远不会知道错误的部分不是代码stream,而是内存使用/ CPU使用率exception。 确定问题的types并报告相关日志进行调查。

  4. 代码审查和演练 :开发团队不能永远等待在他们的最后再现这些问题,然后采取行动。 应当调查错误报告和可用日志,并在此基础上从devise和代码中确定各种可能性。 如果需要的话,他们应该为可能的根本原因准备修补程序,并在包括testing人员在内的团队中传播修补程序,以确定是否可以重新生成错误。

  5. 在确定和检查一个修复程序后,不要通过单个testing人员/团队的观察来解决这些问题 :或许最重要的部分是采取措施来解决这些问题。 一旦检查到这些问题的解决办法,应通知所有位于不同地点的testing/validation团队进行密集型testing,并确定是否存在回归错误。 只有他们中的大部分(实际上大多数)报告为不可重复的,closures评估必须由高级pipe理人员进行。

如果不能重现,可以获取日志,精确重现步骤的截图。

在Windows 7中有一个很好的新function,允许用户logging他们正在做的事情,然后发送一个报告 – 它作为一个文档与每个阶段的屏幕截图。 希望这会有助于用户与应用程序进行交互,而开发人员不会想到的。 我已经看到了很多的错误,只是开发人员使用应用程序的逻辑方式不适合最终用户的实际操作……这导致了很多细微的错误。

被接受的答案是最好的一般方法。 在较高的层次上,值得重视的是修正错误的重要性,而不是将其作为一项function添加到function中,或者增强function以​​使用户受益。 难以重现的错误需要两天才能解决? 在那个时候可以添加一个function,让用户比错误修复更有效? 也许用户会喜欢这个function。 我曾经被视为一名开发人员,关注我可以看到的不完善之处,然后要求用户提供反馈,而他们中没有一个提到我可以看到的错误,但是软件缺less一个他们真正想要的function!

有时,试图在debugging时重现错误的简单持久性可能是最有效的方法。 为了使这个策略起作用,错误需要是“间歇性的”,而不是完全“不可重复的”。 如果你可以在10次重复一次bug,而且你对最可能发生的地方有了想法,那么你可以在这些地方设置断点,然后顽强地试图重复错误,看看到底发生了什么。 我经历过这种情况,要比login一两个案件更有效(虽然日志logging一般是我的第一个问题)。