Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto ...

y_taka_23
December 14, 2024

NilAway による静的解析で「10 億ドル」を節約する #kyotogo / Kyoto Go 56th

Kyoto.go #56 オフライン忘年 LT 会で使用したスライドです。

y_taka_23

December 14, 2024
Tweet

More Decks by y_taka_23

Other Decks in Technology

Transcript

  1. #kyotogo 無効な参照によるエラー • 10 億ドルの過ち(The Billion Dollar Mistake) ◦ null

    を「発明」した Hoare による 2009 年の後悔の言 ◦ Dijkstra 「独身者が全員一人の null と重婚した状態」 • nil 参照は実行時エラーとしてはかなり厄介 ◦ あらゆる型に対し nil チェックが必要になってしまう ◦ 原因と結果がコード的にも時間的にも遠く離れがち 参考:https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare/
  2. #kyotogo NilAway の特徴 • ソースコードから静的に nil エラーを発見 ◦ 関数やパッケージを跨いだエラーが検知可能 ◦

    nil になり得る具体的な原因をメッセージとして表示 • go/analysis パッケージを使用 ◦ 内部は複数の Analyzer でモジュール化され並列動作 ◦ golangci-lint や bazel+nogo などのツールから呼び出し可能 参考:静的解析のモジュール化(https://zenn.dev/tenntenn/books/d168faebb1a739/viewer/9d590e)
  3. #kyotogo NilAway による検査結果 • ソースコードの nil flow を解析 ◦ foo()

    が nil リテラルを返却(10 行目) ◦ foo() を参照(6 行目)
  4. #kyotogo nil flow による因果推論 • nil の発生と参照の因果関係を辺としたグラフを構築 ◦ 発生:nil リテラル、var

    宣言、関数の引数など ◦ 参照:デリファレンス、フィールドアクセスなど • 各ノードに対して「nil であり得るか」をマーク ◦ 発生側を true、参照側を false として伝播・確定させていく ◦ true かつ false の矛盾したノードが現れたら nil エラー
  5. #kyotogo *foo(x, bar()) bar() foo の x foo の y

    foo(x, y) main の x bar の nil リテラル var 宣言 引数 return 引数 デリファレンス return if x == nil
  6. #kyotogo *foo(x, bar()) bar() foo の x foo の y

    foo(x, y) main の x bar の nil リテラル var 宣言 引数 return 引数 デリファレンス return if x == nil 赤は nil 確定 緑は nil 不可能 黒は矛盾
  7. #kyotogo *foo(x, bar()) bar() foo の x foo の y

    foo(x, y) main の x bar の nil リテラル var 宣言 引数 return 引数 デリファレンス return if x == nil 赤は nil 確定 緑は nil 不可能 黒は両方(矛盾)
  8. #kyotogo 冒頭の第 3 問への回答 • ちゃんとした形式化の複雑さ ◦ 人間も基本的には因果関係を辿って nil を発見

    ◦ 意外なトリックがあるという感じではない ◦ しかしアルゴリズムに落とし込むとなると割と複雑 • 計算機科学の裏付けによるスケール可能性 ◦ 因果グラフ推論は 2-SAT 問題とみなせ、線形時間で判定可能
  9. #kyotogo まとめ • nil 参照は厄介なタイプの実行時エラー ◦ 考案者 Hoare 自身も後に「10 億ドルの過ち」と認める

    • NilAway により静的に解析が可能 ◦ nil の可能性を制約としてグラフ上で伝播させ矛盾を検出 • 人間が頭の中で行う「普通にわかる」の形式化 ◦ 意外と複雑な処理だが、厳密に記述できればスケール可能