你如何在ruby中查看调用堆栈的示例?

时间:2011-06-12 14:39:05

标签: ruby-on-rails ruby optimization profiling

我正在调查不同的优化技术,我发现这篇文章Analyzing Code for Efficiency?的人认为对调用堆栈进行抽样比使用分析器更有效。基本思想是,如果您查看调用堆栈,您会看到应用程序最有可能花费大部分时间的位置,然后在那里进行优化。

这当然很有趣,他显然是这方面的专家,但我不知道如何在ruby中查看调用堆栈。在调试器中,我可以说“信息堆栈”,但似乎只显示一行。

编辑:我看到Mike Dunlavey的评论:“我只想指出,如果你在调试器下运行,手动中断它,并显示调用堆栈......”

我只是不确定如何手动中断它并且调用堆栈。

3 个答案:

答案 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>'