BLOGTIMES
2014/12/27

Ruby 1.8 でも Thread#backtrace したい

  ruby 
このエントリーをはてなブックマークに追加

Ruby でマルチスレッドなプログラミングをしていると、自分が起こした Thread が今何をやっているか調べたくなることがあります。そんなときのために Ruby 2.0.x からは Thread#backtrace が導入されているのですが、今回は 1.8.x で動いているシステムで同じことがやりたかったので、何か良い方法がないか模索することに。

ネットを探していると thread_backtrace という gem を見つけました。Experimental とあるのでちょっと心配でしたが、gem install thread_backtrace だけで普通にインストール&実用できました。ただ、この gem がサポートしているのは 1.8 だけで 1.9 はサポートされていないのでその部分は注意が必要なようです。

例えば以下のようなプログラムがあった場合に、これを実行するとこんな感じの結果を得ることができます。

test.rb

require 'rubygems' require 'thread_backtrace' class A def m1 ; sleep 3 ; m2 ; end def m2 ; sleep 3 ; end end t = Thread.new { A.new.m1 } p t.backtrace sleep 5 p t.backtrace sleep 5 p t.backtrace

実行結果

["test.rb:5:in `m1'", "test.rb:9", "test.rb:9:in `initialize'", "test.rb:9:in `new'", "test.rb:9"] ["test.rb:6:in `m2'", "test.rb:5:in `m1'", "test.rb:9", "test.rb:9:in `initialize'", "test.rb:9:in `new'", "test.rb:9"] test.rb:14:in `backtrace': killed thread (ThreadError) from test.rb:14

スレッドが既に終了している場合には ThreadError が投げられるようですね。
Ruby 2.0 の backtrace のリファレンスには「スレッドがすでに終了している場合は nil を返します。 」とあるので、このあたりの仕様の違いには注意する必要がありそうです。


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/7289
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン