我所见过的最奇怪的Bug

Bug 千千万,文中提到的 bug,你遇见过吗?

原文链接:https://engineering.gusto.com/the-weirdest-bug-ive-seen-yet/

未经允许,禁止转载!

作者 | Amy Lai       译者 | 弯月

责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

问题介绍

最近,我们收到了一份报告,说用户在使用内部软件时Chrome突然崩溃了。这导致我们正常的客户服务受到了各种干扰,他们在回复客户的电子邮件或与客户通话期间,突然就看不到工作所必需的客户账户信息了。

图:Chrome窗口崩溃

本来这并不属于我们的工作范围,通常浏览器兼容性之类的问题由其他团队负责,所以我对调试浏览器一窍不通。我应该从哪里着手呢?于是,我求助于一位经验更丰富的队友,我们的产品基础设施团队以及IT团队。

第一条线索

我们首先尝试找出受影响的用户有哪些共同点。

我们很快了解到:

  • 并非所有员工都受到了影响。

  • 面向客户的软件似乎没有受到影响。

  • 其他内部软件页面似乎都很正常。

  • 这个页面并不是每次都会崩溃。遇到此问题后,用户反复尝试重新加载该页面,有时会崩溃,而有时则不会。

  • 并非所有的内部页面都会崩溃,但其中有多个页面崩溃,包括访问最多的页面。

  • 在Safari或Firefox中未发生此问题。

猜测一:Chrome的版本问题

我们最初猜测可能是Chrome的版本问题。于是,我们让其中一个受影响的用户升级他们的Chrome版本,初步迹象看起来问题有希望得到解决。然而,我们很快了解到,尽管安装新的Chrome版本后,页面的崩溃频率降低了,但问题并没有得到根除。

此次尝试,我们获得了以下新线索:

  • 特定Chrome版本的发布已经有一段时间了。

  • 受影响的用户使用了不同版本的Chrome。

  • 使用相同版本的Chrome版本,有的用户受到了影响,而有些则未受影响。

  • 升级/降级受影响用户的Chrome版本无法解决问题。

猜测二:Chrome扩展问题

也许是Chrome扩展的问题?我们尝试让其中一个用户禁用了三个核心扩展,崩溃就停止了,于是我们以为问题得到了解决。然而,当我们尝试使用访客配置文件(没有扩展)重现修复操作时,仍然看到了崩溃。我们又回到了起点。

难以重现的bug

我们的基础设施团队向所有工程人员发送了一条消息,询问是否有人能够重现这个问题。令人沮丧的是,尽管我们的许多客户服务代表都受到了影响,但除了两名土耳其的工程师外,所有工程团队都没有报告任何崩溃。经过几周的努力,我们逐渐了解到以下情况:

  • 出于安全原因,我们未启用Chrome崩溃报告。

  • 从几周前的代码库中检出代码并没有解决问题,这表明该问题不是由于最近的代码变更引起的。

  • 加载页面的静态HTML版本并不会引发崩溃。

  • 使用开源的Chromium代替Chrome不会引发崩溃,因此我们无法得知哪一段Chrome代码出现了问题。

  • 引起Chrome崩溃的不仅仅是一个内部应用,还有好几个。

  • 删除页面的特定内容并没有解决问题。

  • 禁用内部字体并没有解决问题。

为了回避这个问题,我们的用户开始使用其他浏览器,因此这个问题的紧迫性也有所缓解。由于还有其他重要的工作,因此这个bug的调查进度缓慢。在无法重现Bug的情况下,我们没有太多的线索。然而,我们希望解决这个问题,因为用户在Chrome中设置了书签/设置/首选项。我们认为,我们不应该要求用户避免使用这款流行的浏览器,并且我们仍然会定期收到来自各种用户的询问,问我们这个Bug的调查是否有了进展。

好运降临

有一天,一名工程师突然报告说她也受到了影响。她唯一的改变是下载了Grammarly桌面应用程序。

等等,真的吗?我们必须试试看能否重现这个bug。

  • 下载Grammarly桌面应用程序。问题立即重现了!

  • 删除Grammarly。问题没有消失。重启电脑,问题又消失了。

  • 重新安装Grammarly。Chrome又开始崩溃了。

我们与许多受影响的用户确认,他们也在计算机上安装了Grammarly。于是,我们有了突破口!

进展

由于调试能力得到了极大改善,所以我们进行了一些尝试:反复修改代码,然后重新加载页面,直到页面崩溃。

我们的主内部应用构建于ActiveAdmin之上,但新的一部分使用了React。用React构建的页面没有崩溃。这么说是我们的ActiveAdmin代码引发了崩溃?

早些时候,我们了解到删除页面上的特定内容无法解决问题,因此我们开始查看多个页面共同的代码,比如主导航栏和侧边栏。值得注意的是,我们的React页面使用了不同的导航栏。

我们的主导航栏代码涉及很多元编程,追踪这些线索常常会让人更加困惑。最终,我们弄清楚了如何注释掉导航栏的一部分,直到最后我们找到了一行代码,注释掉该行代码Chrome就不会再崩溃:

这个小节叫做“My History”,它不同于主导航的其余部分,所有用户看到的内容不一定相同,它是针对每个用户定制的,显示的是每个用户最近访问的几个页面。我们发现即使页面成功加载,将鼠标悬停在“My History”上也会导致Chrome立即崩溃。

接近真相

猜测三:Turbo

我们的目光停留在了turbo: true。这可能是导致问题的原因吗?Turbo是一个gem,是我们为了提高Rails应用程序的速度而添加进来的,但事实证明这并非问题所在:Turbo是在Bug报告之后才引入的,我们了解到引入Turbo的工程师在这之前的几个月就遇到过Chrome崩溃的问题,甚至在问题报告给我们之前几个月。

那么dropdown的定义在哪里呢?我们使用一款名为Arbre的框架从这种类型的方法中元编程HTML。为了浏览内部结构,我向中一位对Rails有深刻了解的工程师寻求帮助。最后获得的相关代码如下:

这段代码生成的HTML如下:

我们用生成的HTML替换dropdown的调用,然后逐步删除这些HTML,直到最后我们锁定了罪魁祸首。

真相大白

当我删除loader-spinner.gif(菜单选项加载时显示的占位符)之后,页面停止崩溃。真相揭晓!就是这个gif!我们替换成了另一个gif,页面没有崩溃。

我们下载了这个图片文件,将其拖入浏览器窗口。伴随着莎士比亚式的戏剧化,页面当即崩溃了。我和同伴都倒吸了一口气。

我们还发现:

  • 在Safari中打开该文件不会导致崩溃。

  • 卸载Grammarly并重启计算机后,在Chrome中加载该文件不会崩溃。

于是,我们通知了设计系统团队这个非常奇怪的现象,这个导致Chrome崩溃的gif,他们迅速换了一个新的文件。

为什么在安装了Grammarly的情况下,这个特定的gif会导致Chrome崩溃?不幸的是,由于无法访问Chrome和Grammarly的源代码,所以我们只能猜测。在我们替换了这个gif之后,Grammarly或Chrome(或二者共同)都解决了这个问题,因为原来的gif也不会再导致Chrome崩溃了。

结束语

我永远都想不到调试的尽头有一个gif在等着我。

尽管我们找到了解决方法,但在这期间内,这个bug的优先级也发生了变化,但最终我们的好奇心战胜了一切。虽然无法靠个人的力量独自解决这个bug,但我们通过坚持不懈的努力和共同协作,最终解决了这个问题。

本文文字及图片出自 CSDN

余下全文(1/3)
分享这篇文章:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注