我正在调查不同的优化技术,我发现这篇文章Analyzing Code for Efficiency?的人认为对调用堆栈进行抽样比使用分析器更有效。基本思想是,如果您查看调用堆栈,您会看到应用程序最有可能花费大部分时间的位置,然后在那里进行优化。
这当然很有趣,他显然是这方面的专家,但我不知道如何在ruby中查看调用堆栈。在调试器中,我可以说“信息堆栈”,但似乎只显示一行。
编辑:我看到Mike Dunlavey的评论:“我只想指出,如果你在调试器下运行,手动中断它,并显示调用堆栈......”我只是不确定如何手动中断它并且调用堆栈。
答案 0 :(得分:77)
刚刚放
puts caller
代码中的任何位置。如果您不喜欢它的格式,它是一个字符串数组,因此您可以对所需的输出进行一些正则表达式操作。
答案 1 :(得分:6)
如何向ruby进程发送信号,并为转储所有堆栈的信号创建处理程序?
从http://le-huy.blogspot.com/2012/04/dump-backtrace-of-all-threads-in-ruby.html我们有这个例子:
require 'pp'
def backtrace_for_all_threads(signame)
File.open("/tmp/ruby_backtrace_#{Process.pid}.txt","a") do |f|
f.puts "--- got signal #{signame}, dump backtrace for all threads at #{Time.now}"
if Thread.current.respond_to?(:backtrace)
Thread.list.each do |t|
f.puts t.inspect
PP.pp(t.backtrace.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
else
PP.pp(caller.delete_if {|frame| frame =~ /^#{File.expand_path(__FILE__)}/},
f) # remove frames resulting from calling this method
end
end
end
Signal.trap(29) do
backtrace_for_all_threads("INFO")
end
然后我们需要将信号发送到适当的过程:
ps afxw | grep ruby
kill -29 <pid>
ls -l /tmp/ruby*
vi /tmp/ruby_backtrace_...
在适当的采样时间重复信号。
答案 2 :(得分:4)
您可以随时抛出异常,然后查看$@
预定义变量,该变量返回一个回溯数据数组。例如。把它放在foo.rb:
begin
raise 'foo'
rescue
puts $@
end
然后运行它:
$ ruby foo.rb
foo.rb:2:in `<main>'