いざ事例を探そうとすると思うように探せないので、何となくまとめておこう。好きなように足してください。自分で書いてリンクするのも歓迎。360ハードウェアバグ。抽象化が漏れる事例として非常に興味深い。ゲームで性能を出すために、L2キャッシュをバイパスするプリフェッチ命令を追加した。バイパスすると一貫性が保証できなくなる。プリフェッチしてしまうと、その部分がCPU間で食い違いクラッシュした。同様のクラッシュが起きる。メモリダンプをいくら眺めても原因がわからない。犯人は分岐予測による投機実行だった。本来実行されないはずのプリフェッチ命令が実行されてしまうことがある。効果を発揮してしまっていたのだ。投機実行の正当性の前提は、投機実行されるコードが副作用を持たないことだ。この「副作用」の範囲はどこまでか。通常考えるのはCPUのISAレベルで扱う、レジスタやメモリの状態だ。キャッシュはその状態に対して透過的に動作するはずで、論理的な動作モデルとは分離されているはずだった。その抽象化の壁が壊れる事例のひとつ。本人の体験ではないけれど、おもしろいので。オーバーフローに起因するバグ2題。Libraryメモリリークを追いかける話。消費しないはずのプロセスがGB単位でがんがんメモリを増やしてこける。増えているメモリは実際に使われてると判断されてる。アロケータの癖でフラグメンテーションか何かを引き起こしてる可能性を考え、アロケータをjemalloc差し替えてみる。jemallocのツールでアロケートされるチャンクの分布を見てみると、プログラムでは小さい単位でしかアロケートしてないはずなのに、大きなチャンク単位でmallocが発行されている。テンプレートの迷路をさまよい諦めかけた刹那、newの実装を見てなかったことに気づく。「mallocは遅い」時代の産物であろう。このアプリケーションが、その独自アロケータのハマりパターンを突いてしまっていたらしい。グローバルに環境変数で独自アロケータを使わなくするオプションがあるのでそれで解決。条件が変わると逆にお荷物になり得るんだよな。それを見直すのは難しい。広く使われて概ね動いている実績があるほど、動いてるコードには触るな、になりがちだし。それはそれとして原因を追ってく過程が詳細でおもしろかった。caching特定のアーキテクチャでMonoを使ってるソフトがランダムにSIGILLで落ちる。デバッガで見ても該当アドレスのインストラクションは正しい。調べてみても変なことはやっていない。この可能性を思いつくこと自体が難しいだろうなあ。バグの症状からパターンを見つけてそれを解決につなげる過程が見事。specificationlocalhostへのtcp接続がたまにtimeoutする。サーバが取りこぼしてるわけではない。SYNパケットの返事が来ない。?原因を突き止める経緯が参考になる。忘れてて、クライアントがいなくなった後でもソケットがCLOSE_WAITのままになっていた。無視してた、というわけ。bug!めっちゃ基本的な関数にもバグが残ってることがある。このミスは自分も経験あるけど、ソースだけをいくら眺めてもわからないんだよね。Smedium.comのオンラインエディタで、ポーランド語のŚだけが何故か入力できない、というバグ。技術的に複雑な話ではなく、むしろ原因は歴史的あるいは文化的なものだ。バグは技術と文化の界面に生じるものなのかもしれない。コードが変わらなくても、コードを取り巻く環境が変わればかつての仕様は新たなバグになり得る。boot組み込みLinuxデバイスが時々死ぬ問題を追いかける話。追いかける過程が丁寧に書かれているのが参考になる。bugガウス分布を生成するコードが非常に稀にクラッシュするというバグレポートを受け取った。その部分のコードは世界中で使われているRANLIBから持ってきたもの。これが正確な0を返した場合にクラッシュする、という問題がRANLIBの元のコードにあることを発見。論文でそう書いてあるからだ。元論文に閉区間と開区間を取り違えるバグがあった。その実装でたまたま他のみんなが(論文に反して)開区間の発生器を使っていたため、そのバグは41年間表面化しなかった。これだけ使い込まれたコードにも潜んでいることがあるというのは興味深い。隠された遺伝的変異に喩えている。DeathLinuxでSIPアプライアンスを作っている人。手元ではどうしても再現しない。手元で火を入れてテストするとちゃんと動く。問題を手元で再現する手がかりを見つけるまで数ヶ月。そこからさらに絞り込んで、最終的な再現条件を見つけるまでがまた大変。デバッグに銀色の弾丸なし、地道な調査あるのみだなあ。couldn'tロンドンからモントリオールへのssh転送が時々失敗する。パケットダンプから原因を追いかけ、失敗しているノードの特定まで。いう状況で、自分から触れる道具を駆使して原因を追い詰めてゆくところ。向井さんのG+ポストより。valgrindの思い出valgrindがリークをレポートした。デストラクタで開放してるのに...コードを良く見たらデストラクタに至る前にSIGTERMで終了してた。いや、でも他にもデストラクタが呼ばれてないデータはたくさんあるのにvalgrindはレポートしてないよ?手がかりが見つかったと思ったら違ってて、また新たな手がかりが見つかって...と二転三転するミステリのようなバグ譚。コンパイラのバグなぜか無関係なパッチでMacのビルドだけが壊れる。はじめはMacのビルド環境がflakyなだけかと疑ったが......。crash(高林さんのポスト経由)。Windows上での謎のクラッシュを追い詰める。instrumentationを仕込んで原因を絞って行く話。Ports(鵜飼さんのGoogle+のポスト経由)。ストーリーは淡々と語られてるけど、技術的なディテイルが詳しく語られてて参考になる。即席のカーネル拡張を書いてしまうあたり、著者の並ならぬ体力を感じさせてくれる話である。大幅に遅くなったという話。機能テストにはひっかからないのが厄介。Storiesハードウェアのバグ。やってバグを絞り込んだかが面白い。unexplainable....データベースサーバが謎のトラブル。email物理的に500マイル以上離れたサイトにメールが届かない、というユーザからのクレーム。emailの配送に物理的距離は関係ないだろう、何かの間違いでは、と思ったが事実だった。glibcが複雑に絡み合ったバグの追跡。因果律を否定するバグテストを足したら、別のテストがメモリを食いまくって落ちる。落ちる時点では、足したテストはまだ実行されていないのだ。20年前に自分で書いたハッシュテーブルのコードに行き当たった。何の変哲もないごく普通のコード。枯れたコードでも、暗黙の前提が変わればバグは出る。Poisonソースの無いアプリケーションがハングする。クラッシュするコードを仕込んでみた。ハングもクラッシュもせずに。encounteredプレステ3でデバッグ中に原因不明の一時的フリーズが起きる。チーム総出で連続デバッグプレイしている時しか起きない。起きるときは複数のマシンで同時に起きる。ログを仕込んでみるが、フリーズ時には通信は行われていない。フリーズ時のメモリ状態を解析するも、フリーズ箇所はばらばら。