宇宙光線がプログラムをクラッシュさせる
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で見る
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が戻った!