メモリ corruption の話。
中田さんに http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20140821T220302Z.fail.html.gz みたいなエラーが出ていると指摘され、重い腰をあげる。どうやら、
./miniruby -I../trunk/lib -I. -I.ext/common ../trunk/tool/transcode-tblgen.rb -vo enc/trans/single_byte.c ../trunk/enc/trans/single_byte.trans
このコマンドでエラーが出ていることがわかったので、これを valgrind 上で実行すれば良かろう、と思い、
while make miniruby && rm enc/trans/single_byte.c -f && valgrind ./miniruby -I../trunk/lib -I. -I.ext/common ../trunk/tool/transcode-tblgen.rb -vo enc/trans/single_byte.c ../trunk/enc/trans/single_byte.trans; do date; done
と実行して方っておいても、異常終了してくれない。
なので、手動 bisect みたいなこと(つまり、svn up でリビジョンを巻き戻す)をするも、わけわかんねーところ(ruby スクリプトのコード変更)あたりで止まってしまう。つまり、その ruby スクリプトの変更が、なんらかのひこう(なぜか変換出来ない)をついてしまったようだ。
で、どうしようもなくて、他のツールを使ったりしてたけど全然再現せず、
ここで valgrind で使うべきオプションは次の 3 つであった。
とりあえず、--error-exitcode を知らないで、画面をぼーっとしていたら invalid write が起きていて気づけたという話(多分)。
まぁ、色々ツールの使い方は気をつけてみるといいかもね、という。
治った結果が http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=47252。間違ってるけど(最初 goto で書いてたので...)。
実は手作業 bisect で色々追い詰めておいたのが、バグ再現で重要だったようだ。なんか、最新版(の直す前の一歩手前)で valgrind かけてもさっぱり出てこない。
再現コードがあって、本当によかった。
あるマシンで何度か同じベンチマークを走らせたところ、どんどん遅くなることが観測できた。何事かと色々調べてみると、CPU の温度が高くなりすぎ、という話らしい。
Aug 13 05:10:49 i5 kernel: [36485.975613] CPU0: Core temperature above threshold, cpu clock throttled (total events = 192410)
こんな感じ。
lm-sensors をインストールして、coretemp に対応していることがわかったので、sensors コマンドで見てみると、
coretemp-isa-0000 Adapter: ISA adapter Core 0: +39.0°C (high = +83.0°C, crit = +99.0°C) ALARM (CRIT) Core 1: +42.0°C (high = +83.0°C, crit = +99.0°C) ALARM (CRIT) Core 2: +39.0°C (high = +83.0°C, crit = +99.0°C) ALARM (CRIT) Core 3: +42.0°C (high = +83.0°C, crit = +99.0°C) ALARM (CRIT)
こんなのが見れるんだけど、ベンチマーク走らせたら 99度までいくことが観測できた。 火事になるな、これは...。
どうしたものか。