4
3

More than 5 years have passed since last update.

[CRuby] Ruby VM 周辺(Kernel.#set_trace_func)

Posted at

Sasadaさんが2012年に行っていたRuby VM アドベントカレンダーを読んで、

  • Kernel.#set_trace_func
  • TracePoint
  • TracePoint API
  • Debug Inspector API
  • RubyVM::InstructionSequence

このあたりの内容に興味を持ったので、少し手を動かしてみよう。
バージョンは2.0.0p195 (2013-05-14) [i386-mingw32]

Kernel.#set_trace_func

とりあえずはset_trace_func

参考にしたのは
リファレンスマニュアル
Sasadaさんの2012/12/12の記事
takihiroさんの記事
README.EXT.ja
Code Reading Wiki
ひとり勉強会

set_trace_funcの簡単な使い方

trace.rb
1 : set_trace_func lambda { |*args| 
2 :   p args
3 : }
4 :
5 : class Foo
6 :   def bar
7 :     p "Hello"
8 :   end
9 : end
10:
11: foo = Foo.new
12: foo.bar

# =>
["c-return", "trace.rb", 1, :set_trace_func, #<Binding:0xf6c540>, Kernel]
["line", "trace.rb", 5, nil, #<Binding:0x10cba80>, nil]
["c-call", "trace.rb", 5, :inherited, #<Binding:0x10cb840>, Class]
["c-return", "trace.rb", 5, :inherited, #<Binding:0x10cb600>, Class]
["class", "trace.rb", 5, nil, #<Binding:0x10cb3a8>, nil]
["line", "trace.rb", 6, nil, #<Binding:0x10cb198>, nil]
["c-call", "trace.rb", 6, :method_added, #<Binding:0x10caf88>, Module]
["c-return", "trace.rb", 6, :method_added, #<Binding:0x10cad48>, Module]
["end", "trace.rb", 9, nil, #<Binding:0x10cab20>, nil]
["line", "trace.rb", 11, nil, #<Binding:0x10ca910>, nil]
["c-call", "trace.rb", 11, :new, #<Binding:0x10ca700>, Class]
["c-call", "trace.rb", 11, :initialize, #<Binding:0x10ca4c0>, BasicObject]
["c-return", "trace.rb", 11, :initialize, #<Binding:0x10ca280>, BasicObject]
["c-return", "trace.rb", 11, :new, #<Binding:0x10ca058>, Class]
["line", "trace.rb", 12, nil, #<Binding:0x10c9e30>, nil]
["call", "trace.rb", 6, :bar, #<Binding:0x10c9c08>, Foo]
["line", "trace.rb", 7, :bar, #<Binding:0x10c99e0>, Foo]
["c-call", "trace.rb", 7, :p, #<Binding:0x10c97a0>, Kernel]
["c-call", "trace.rb", 7, :hash, #<Binding:0x10c9560>, Kernel]
["c-return", "trace.rb", 7, :hash, #<Binding:0x10c9338>, Kernel]
["c-call", "trace.rb", 7, :inspect, #<Binding:0x10c9110>, String]
["c-return", "trace.rb", 7, :inspect, #<Binding:0x10c8eb8>, String]
"Hello"
["c-return", "trace.rb", 7, :p, #<Binding:0x10c8bb8>, Kernel]
["return", "trace.rb", 8, :bar, #<Binding:0x10c8990>, Foo]

イベントは

  • "line": 式の評価。
  • "call": メソッドの呼び出し。
  • "return": メソッド呼び出しからのリターン。
  • "c-call": Cで記述されたメソッドの呼び出し。
  • "c-return": Cで記述されたメソッド呼び出しからのリターン。
  • "class": クラス定義、特異クラス定義、モジュール定義への突入。
  • "end": クラス定義、特異クラス定義、モジュール定義の終了。
  • "raise": 例外の発生。

があり、それぞれが実行される度に設定したprocが呼ばれます。

argsはそれぞれevent, file, line, id, binding, klassになっています。
先頭でKernel.#set_trace_funcを呼び出しておけば、それ以降のイベントをフック出来ます。

Ruby標準ライブラリ

リファレンスマニュアルにも書いてあるとおり、

  • debug
  • tracer
  • profile

set_trace_funcを利用しているそうです。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3