こんにちは、Rubyist九州の新井です。
Railsなどを実行していると、たまにハングすることがありますが、
そのときにデバッグに苦慮することがあります。
gdbでattachして内容を確かめることもありますが、運良く情報が
簡単に得られて解決したのは1度きりで、大体の場合、
僕のスキルではgdbを使って問題解決するのは難しいようです。
たまに発生するハングアップの場合は、常時詳細なログを取って
デバッグすることも難しいですし、困ってしまいます。
そこで末尾に付属したようなコードを書いて、もしプログラムが
長期間動きっぱなしになっている場合はタイムアウトを発生させ、
そのときのbacktraceを取得できる、という方法を考えました。
しかしRailsの場合、これを組み込むのも容易ではない感じです。
どこかでExceptionをrescueしていれば終わりですし。
何か良い策はないものでしょうか?
他スレッドの内容をダンプしたり、もしくは実行中のRubyプロセスの
内容をダンプ・解析するような方法があれば、是非ご教示頂きたく存じます。
--- ここから ---
class ThreadTimeout < Exception
end
class Watchdog
attr_accessor :timeout
def initialize
@timeout = 120
end
def run
t = nil
start = Time.now
t = Thread.new {
begin
Thread.current[:retval] = yield
rescue ThreadTimeout => e
Thread.current[:timeout] = e
rescue Exception => e
Thread.current[:exception] = e
end
}
while(t.alive?)
if (Time.now - start) > @timeout
t.raise(ThreadTimeout.new)
end
end
if t[:timeout]
puts t[:timeout]
puts t[:timeout].backtrace
return nil
end
raise t[:exception] if t[:exception]
t[:retval]
end
end
--- ここまで ---
-----
Mellowtone Inc. - life is a melody
Shunichi Arai
http://www.mellowtone.co.jp
http://asiajin.com/blog/