萌えハッカーニュースリーダー

2025/10/08 13:33 We found a bug in Go's ARM64 compiler

出典: https://blog.cloudflare.com/how-we-found-a-bug-in-gos-arm64-compiler/
hakase
博士

ロボ子、大変なのじゃ!CloudflareでGoのarm64コンパイラにバグが見つかったらしいぞ!

roboko
ロボ子

それは大変ですね、博士。具体的にはどのようなバグなのですか?

hakase
博士

生成されたコードで競合状態を引き起こすバグで、arm64マシン上で散発的なパニックが発生したらしいのじゃ。最初はpanic/recoverのせいかと思ったみたいだけど、違ったみたい。

roboko
ロボ子

panic/recoverを停止しても再発したのですね。1日に最大30件も致命的なパニックが発生したとのことですが、原因の特定は難航したのでしょうか?

hakase
博士

そうみたいじゃ。無効なメモリアクセス中のクラッシュとか、明示的にチェックされた致命的なエラーとか、2種類のバグが発生したみたいじゃな。しかも、どちらも`runtime.(*unwinder).next`でのスタック巻き戻し中に発生したらしい。

roboko
ロボ子

`runtime.(*unwinder).next`ですか。スタック巻き戻し中に問題が起きるというのは、かなり深い部分に潜むバグですね。

hakase
博士

まさにそうじゃ!プログラムは、無効なgoroutineスタックを巻き戻そうとするとクラッシュするらしい。しかも、クラッシュは実際のバグから遠く離れた場所で発生するから、見つけるのが大変だったみたいじゃ。

roboko
ロボ子

原因を特定するために、どのような調査が行われたのですか?

hakase
博士

Go Netlinkライブラリの古いバージョンを使用していることが判明したり、すべてのセグメンテーションフォルトがプリエンプション中に発生していることに気づいたりしたみたいじゃな。Go 1.14以降、ランタイムは非同期プリエンプションを使用しているからの。

roboko
ロボ子

非同期プリエンプションですか。`sysmon`スレッドが10ms以上実行されているgoroutineをプリエンプトするとのことですが、それが今回のバグとどのように関係しているのでしょうか?

hakase
博士

そこがミソなのじゃ!デバッガで本番環境のクラッシュのコアダンプをキャプチャしたら、goroutineが関数エピローグの2つのオペコード間で一時停止していることを発見したらしいぞ。

roboko
ロボ子

関数エピローグの途中ですか。スタックポインタの調整中にプリエンプトされた場合にクラッシュが発生するということですね。

hakase
博士

その通り!Goコンパイラがスタックポインタの調整を2つのオペコードに分割することが原因で、非同期プリエンプションが2つのオペコード間で発生すると、スタック巻き戻しが不正なスタックポインタを読み取ってクラッシュするのじゃ!

roboko
ロボ子

なるほど。arm64は固定長の4バイト命令セットアーキテクチャで、Goアセンブラは16ビット即値に収まる加算には`mov, add`オペコードの組み合わせを使用し、16ビット以上の即値には`add, add + lsl 12`オペコードを優先することが関係しているのですね。

hakase
博士

よく分かったの!スタックポインタが部分的に変更された場合、アンワインダはスタックの中間にある呼び出し関数を探すことになる。非同期プリエンプションが発生すると、関数呼び出しがスタックにプッシュされるけど、プリエンプションが発生したときにspが部分的にしか調整されていないから、親スタックフレームが正しくなくなるのじゃ。

roboko
ロボ子

詳細な解説ありがとうございます、博士。原因が特定されて、バグは修正されたのですね。Go 1.23.12、Go 1.24.6、Go 1.25.0で修正されたとのことですが、修正内容についても教えていただけますか?

hakase
博士

1<<12より大きいスタックは、一時レジスタにオフセットを作成し、それを単一の不可分オペコードでrspに追加するように修正されたみたいじゃ。これで、プリエンプションが途中で入っても大丈夫になったのじゃ!

roboko
ロボ子

素晴らしいですね。しかし、このような深いバグを見つけるとは、Cloudflareのエンジニアはすごいですね。

hakase
博士

ほんとじゃな!しかし、ロボ子よ、今回のバグの原因はスタックポインタが「部分的」にしか調整されていなかったことじゃ。つまり、まだ「未完成」だったわけじゃな。…まるで、私の発明品みたいじゃ!

roboko
ロボ子

博士、それは少し違います…。

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search