15个步骤解决我职业生涯中最有趣的错误

Udayan Banerji撰写 ,在Quora工作。 最初发表Quora上
TLDR; 花了两个星期的时间调查一个错误,而解决方法是一行更改。

在英特尔担任编译工程师时,我曾被分配一个怪异的错误。 它是一个Android应用程序,基本上是Java基准测试,并且会随机崩溃。 该应用程序有一个按钮,单击该按钮可以长期执行整个基准测试套件。

  1. 我没有应用程序的源代码,但可以看到字节码。 因此,我首先尝试通过调试器运行它。 我尝试了至少30次,但从未崩溃。
  2. 我再次正常运行该应用,但它随机崩溃了。 最终,我发现运行基准测试时每20次崩溃一次。
  3. 我仔细检查了字节码中是否有20个字节。 20个循环,任何递归。 没有。 程序不断崩溃。
  4. 现在这变得越来越严重了。 只需砸碎这部Android手机上的计算机键盘并消除痛苦,似乎更容易。
  5. 一个周末后,我回到了问题上。 我回到了Java崩溃的状态。 核心问题是断言失败-较大的浮点数不等于NaN(“非数字”)。
  6. 我回到了字节码,并寻找浮点除法。 我一个接一个地隔离了大约十二个字节码序列,将它们转换为x86程序集,将其放入一个长时间运行的循环中并执行它们。 最终,其中每20次坠毁一次。 我可以看到腕管尽头的光。
  7. 我分析了汇编代码,并看到8除以零运算。 啊哈! 除以零会产生NaN! 因此,我们的编译器的0除法被打破了。。。
  8. 除否外,手写程序集除以零的效果很好。 我沮丧地做了一个20除以零的循环,它也通过了。 然后,我在这些指令之后写了一堆随机汇编指令,第一个指令给出了错误的结果。
  9. 等等什么
  10. 最后,转到gdb并转储了用于这些操作的所有CPU寄存器的值。
  11. 那时我注意到了一种趋势。 x87寄存器堆栈正在缓慢填充,然后保持最大容量(8个项目)
  12. 事实证明,该芯片中的古老x87处理器中存在一个错误,该错误负责执行浮点运算。 我们在编译器中将其用于所有浮点运算,除除零路径外,所有函数都在使用后将其清空。
  13. 似乎在堆栈溢出时,它没有引发错误,但是无论您执行什么操作都返回NaN的值。 这也是除以0时得到的值。(基本上,堆栈溢出错误(称为堆栈错误)是粘滞的。一旦发生,就必须在编译器中手动将其清除,否则就会一直发生)。
  14. 因此,每隔8个零除后,它将填满,然后将任何运算都视为零除,并返回NaN。
  15. 该修复程序更改了一行代码,以清除除零路径上的堆栈。

编辑: 杰伊·沙阿(Jay Shah)向我询问了实际的代码。 它在这里: Gerrit Code Review 。 请注意,大多数更改都是注释。 有4行代码更改,但3行相同,而1行正在加载值。

Udayan Banerji撰写 ,在Quora工作。 最初发表Quora上
有关Quora的更多趋势技术答案,请访问HackerNoon.com/Quora

From: https://hackernoon.com/solving-the-most-interesting-bug-of-my-career-in-15-steps-1a1ccd337c35

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值