宇宙光線がプログラムをクラッシュさせる

http://blog.ksplice.com/2010/06/attack-of-the-cosmic-rays/

kspliceのスタッフが「cosmic bit flip」によるクラッシュを調査。ubuntuでのパッケージプログラムのデバッグの入門書としても読む価値あり。以下は的要約なので、詳細は上のリンクの本文を参照。

いつも使っているgnu coreutilのプログラム「expr」がいきなりクラッシュしはじめた。パッケージや環境にそれらしい変化もない。バイナリの日付もインストールした際のものだ。ログにもそれらしきものは書いていない。さてどうする?

  • まずはパッケージを確定

dpkg -S $(which expr)

  • 問題のパッケージのデバッガーシンボルをインストール

sudo aptitude install coreutils-dbgsym

gdb --args expr 3 + 3
ここである関数のアドレスがおかしいことに気付く。

  • ソースを入手

apt-get source coreutils
これでgdbでソースが見れるようになる。

ここで驚くべき発見: 関数のアドレスのビットが一つだけ違っている!

  • debsumsでファイルのchecksumをチェック。

debsums coreutils | grep FAILED
ここで依存ライブラリではなく/usr/bin/expr自体が違っていることを発見。

  • パッケージをダウンロードしてファイルを比較

aptitude download coreutils
dpkg -x hoge.deb hoge
cmp -bl インストール済みの疑わしいプログラム ダウンロードしたもの

ディスク上のプログラムのビットが一つだけ違っているのだ! しかも、mtimeはインストールしたときのまま。 どうしてこんなことがありうるのか。 ビットが一つ変るってのは例の宇宙光線がメモリチップに当って1bitひっくりかえってしまうという伝説の「cosimic bit flip」か? しかし、ディスク上のイメージだぞ。

cosimic bit flipはディスク上のファイルをも変える

ファイルといってもキャッシュに入ってしまえば、メモリ上のもの。 宇宙光線(よりも壊れたメモリチップ)によって破損することもある。

この記事の著者のデスクトップマシンには12GBのメモリがそなわっている。 (最近2gbにアップグレードして喜んでいるテングだが、そんな時代になったのか、、) なので、問題のプログラムがずっとキャッシュに居座って、宇宙光線かチップエラーによって破損する可能性が高まる。

このセオリーを確認するにはファイルシステムのキャッシュをディスクにsyncすればいい。
/proc/sys/vm/drop_caches
すると見事に/usr/bin/exprのchecksumが戻った!

結論: ファイルシステムのキャッシュにあったプログラムイメージがメモリ破損していた

原因はハードエラー、カーネルのソフトバグという可能性もあるが、1ビットだけ間違えるバグもめずらしい、とくくっている。はやり宇宙光線か、、

感想

  • ubuntu(debianかな)はパッケージのデバッギング環境を揃えるコマンドがそなわっているんだね。 知らなかった。
  • kspliceのブログは読みごたえがあり、勉強になる。さすがシステム屋さん。