web-dev-qa-db-ja.com

Rubyでスタックトレースオブジェクトを取得する方法は?

Rubyでスタックトレースオブジェクトを取得する必要があります。印刷するのではなく、後で分析するために記録とダンプを行うためだけに取得します。それは可能ですか?どうやって?

57
pupeno

これには Kernel.caller を使用できます。例外のスタックトレースを生成するときに同じ方法が使用されます。

ドキュメントから:

def a(skip)
  caller(skip)
end
def b(skip)
  a(skip)
end
def c(skip)
  b(skip)
end
c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
c(2) #=> ["prog:8:in `c'", "prog:12"]
c(3) #=> ["prog:13"]
79
Sven Koschnicke

試して

Thread.current.backtrace.join("\n")
31
Alex Bondar

error.backtrace を試してください:

# Returns any backtrace associated with the exception.  
# The backtrace is an array of strings, each containing either ``filename:lineNo: in `method’’’ or ``filename:lineNo.’‘

def a
  raise "boom"
end

def b
  a()
end

begin
  b()
rescue => detail
  print detail.backtrace.join("\n")
end

生成するもの:

prog.rb:2:in `a'
prog.rb:6:in `b'
prog.rb:10
12
Nikita Rybak

Ruby 2.0+の場合、 Kernel#caller_locations 。基本的に Kernel#callerSven Koschnickeの回答 でカバー)、ただし、文字列の配列を返す代わりに、 Thread::Backtrace::Location オブジェクト。 Thread::Backtrace::Locationは、 pathlineno 、および base_label 。これは、生の文字列だけでなく、スタックトレースに関する特定の詳細にアクセスする必要がある場合に役立ちます。

ドキュメント から:

caller_locations(start = 1、length = nil)→配列またはnil

caller_locations(range)→配列またはnil

現在の実行スタック(バックトレースロケーションオブジェクトを含む配列)を返します。

見る - Thread::Backtrace::Location 詳細については。

オプションの開始パラメーターは、スタックの先頭から除外する初期スタックエントリの数を決定します。

2番目のオプションのlengthパラメータを使用して、スタックから返されるエントリの数を制限できます。

nilが現在の実行スタックのサイズより大きい場合、startを返します。

オプションで、指定した範囲内のエントリを含む配列を返す範囲を渡すことができます。

使用例:

def a
  caller_locations(0)
end
def b
  a
end
def c
  b
end

c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
7
Ajedi32
Thread.current.backtrace

これにより、通常のバックトレースで取得される可能性のあるすべての行を含む配列が作成されます。

3
Rajat Bansal

必要に応じて独自に作成することもできます。 Russ OlsenによるEloquent Rubyで示されているように:

# define a proc to use that will handle your trace 
proc_object = proc do |event, file, line, id, binding, klass| 
  puts "#{event} in #{file}/#{line} #{id} #{klass}"
end 

# tell Ruby to use your proc on traceable events
set_trace_func(proc_object)
2
Sammy Larbi