如何在 Ruby 中获取堆栈跟踪对象?
Posted
技术标签:
【中文标题】如何在 Ruby 中获取堆栈跟踪对象?【英文标题】:How to get a stack trace object in Ruby? 【发布时间】:2011-04-19 06:05:09 【问题描述】:我需要在 Ruby 中获取堆栈跟踪对象;不打印它,只是为了让它做一些记录和转储以供以后分析。那可能吗?怎么样?
【问题讨论】:
【参考方案1】:试试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
【讨论】:
我想我必须抛出异常才能获得堆栈跟踪。 @J.巴勃罗 似乎如此。如果您找到直接获取的方法,请在此处发布。 Sven 用 Kernel.caller 搞定了。【参考方案2】:您可以为此使用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"]
【讨论】:
【参考方案3】:如果您愿意,您也可以创建自己的。正如 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)
【讨论】:
【参考方案4】:试试
Thread.current.backtrace.join("\n")
【讨论】:
【参考方案5】:对于 Ruby 2.0+,您可以使用Kernel#caller_locations
。它与Kernel#caller
基本相同(在Sven Koschnicke's answer 中介绍),不同之处在于它不是返回一个字符串数组,而是返回一个Thread::Backtrace::Location
对象数组。 Thread::Backtrace::Location
提供了诸如path
、lineno
和base_label
之类的方法,当您需要访问有关堆栈跟踪的特定详细信息而不仅仅是原始字符串时,这些方法可能很有用。
来自the docs:
caller_locations(start=1, length=nil) → 数组或 nil
caller_locations(range) → 数组或 nil
返回当前执行堆栈——一个包含回溯的数组 位置对象。
更多信息请参见
Thread::Backtrace::Location
。可选的start参数决定了初始栈的个数 要从堆栈顶部省略的条目。
第二个可选的
length
参数可用于限制多少 条目从堆栈中返回。如果
start
大于当前执行的大小,则返回nil
堆栈。您可以选择传递一个范围,该范围将返回一个包含 指定范围内的条目。
使用示例:
def a
caller_locations(0)
end
def b
a
end
def c
b
end
c.map(&:base_label)
#=> ["a", "b", "c", "<main>"]
【讨论】:
【参考方案6】:Thread.current.backtrace
这将为您提供一个数组,其中包含您在任何正常回溯中可能获得的所有行。
【讨论】:
以上是关于如何在 Ruby 中获取堆栈跟踪对象?的主要内容,如果未能解决你的问题,请参考以下文章