我们是如何在Go的arm64编译器中发现一个错误的

我们是如何在Go的arm64编译器中发现一个错误的

💡 原文英文,约3100词,阅读约需12分钟。
📝

内容提要

Cloudflare在其arm64编译器中发现了一个竞争条件错误,导致堆栈回溯不完整。经过调查,问题与Go Netlink库的异步抢占有关。Go团队最终修复了该错误,确保在修改期间堆栈指针不会被抢占,从而消除了竞争条件。

🎯

关键要点

  • Cloudflare在其arm64编译器中发现了一个竞争条件错误,导致堆栈回溯不完整。
  • 问题与Go Netlink库的异步抢占有关,导致堆栈指针在修改期间被抢占。
  • 最初观察到的错误是堆栈回溯未完全展开,可能是由于堆栈损坏。
  • 经过调查,发现fatal panic与恢复的panic数量相关,导致了对错误处理方式的改变。
  • 最终确认问题与Go Netlink库的Receive函数有关,尤其是在异步抢占期间。
  • 通过创建最小可重现示例,确认了这是一个运行时错误,导致堆栈指针在不一致状态下被修改。
  • Go团队修复了该错误,确保在修改期间堆栈指针不会被抢占,从而消除了竞争条件。

延伸问答

Cloudflare是如何发现Go的arm64编译器中的错误的?

Cloudflare在其arm64编译器中发现了一个竞争条件错误,导致堆栈回溯不完整,经过监控和调查后确认了问题的根源。

Go Netlink库的异步抢占是如何导致堆栈指针被抢占的?

Go Netlink库的Receive函数在异步抢占期间导致堆栈指针被抢占,从而引发了竞争条件错误。

Cloudflare在调查过程中采取了哪些步骤?

Cloudflare通过观察fatal panic与恢复的panic数量的关系,停止使用panic/recover进行错误处理,并创建最小可重现示例来确认错误。

Go团队是如何修复这个竞争条件错误的?

Go团队修复了该错误,确保在修改期间堆栈指针不会被抢占,从而消除了竞争条件。

这个错误对Cloudflare的服务有什么影响?

这个错误导致了在arm64机器上出现间歇性的fatal panic,虽然对大多数服务影响不大,但仍然引起了关注。

如何创建一个最小可重现示例来确认这个错误?

通过编写一个函数,该函数在循环中调用并分割堆栈指针的调整,从而触发错误并确认其存在。

➡️

继续阅读