Mona OSにおけるデバッグ技法 - 1.自動で現象を再現させる


QEMU で何回も Mona を起動して不具合が再現させるの大変。
そういうときに楽をする方法です。

概念

以下のようなフローのスクリプトを作り自動化します。

  1. QEMU を起動する
  2. 1秒 sleep
  3. 正常起動条件の文字列をログに見つけたら QEMU を停止 1 に戻る。
  4. バグ再現条件の文字列をログに見つけたらログの内容を Emacs に表示し exit
  5. 2に戻る

実際の例

例えば Mona の音楽プレイヤが100回に1回くらいの頻度で、アドレス違反で kill されるとしましょう。
不具合を再現させるには、QEMU を起動しじっと待って kill されなければ、QEMU を再起動というのを繰り返すことになります。
仮に再現したとしても、ちょっと手直しをして落ちなくなったかを検証せねばなりません。
これを手でやっていては身が持ちません。

そこで以下の適当スクリプトで自動化します。(汚いのは勘弁)

#!/usr/bin/env ruby

while (true)
  system('qemu -cdrom ~/mona/tool/mkimg/mona.iso -fda ~/mona/tool/mkimg/mona.img -boot d -soundhw pcspk -k ja -serial file:/tmp/qemu_mona.log -soundhw es1370 -net nic -net user -redir tcp:5555:10.0.2.15:5555 -redir udp:5555:10.0.2.15:5555 -vnc :1 &')
  while (true)
    sleep 1
    `grep 'ov_open OK' /tmp/qemu_mona.log`
    if $? == 0
      puts 'QEMU restart'
      `pkill qemu`
      break
    else
      puts 'starting ...'
    end
    `grep 'kill' /tmp/qemu_mona.log`
    if $? == 0
      system('gnuclient /tmp/qemu_mona.log &')
      exit
    end
  end
end

ポイントは4つ
(1)Mona がシリアルポートに吐くログを監視して正常 or エラー再現を切り分けていること
(2)正常起動してしまったら QEMU を自動で再起動していること
(3)エラーが再現したら gnuclient を利用してエラーログを Emacs に送信して notify してくれること。
(4)QEMUを -vnc オプションで起動することで QEMU を別ディスプレイに起動しじゃまにならないようにしていること。(これをやらないと QEMU が起動のたび最前面に来てうざいことに)

これで大分楽ができそうですね。
ちなみにこのドキュメントはバグが再現するまでの待ち時間で書かれています。