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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6322524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 01:22:55  来源:igfitidea点击:

How do you view a sample of the call stack in ruby?

ruby-on-railsrubyoptimizationprofiling

提问by Jeremy Smith

I'm investigating different optimization techniques, and I came across this post Analyzing Code for Efficiency?by someone who believes that sampling the call stack is more effective than using a profiler. The basic idea is that if you take a view of the call stack, you see where your application is most likely to be spending most of its time, and then optimize there.

我正在研究不同的优化技术,我看到了这篇文章分析代码效率?有人认为对调用堆栈进行采样比使用分析器更有效。基本思想是,如果您查看调用堆栈,您会看到您的应用程序最有可能花费大部分时间的地方,然后在那里进行优化。

It is certainly interesting, and he is obviously an expert on this, but I don't know how to view the call stack in ruby. In debugger I can say "info stack" but only seems to show one line.

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

EDIT: I saw this comment by Mike Dunlavey: "I would just like to point out that if you run under the debugger, interrupt it manually, and display the call stack..."

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

I'm just not sure how to interrupt it manually and dipslay the call stack.

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

回答by sawa

Just put

就放

puts caller

anywhere in the code. If you don't like its format, it's an array of strings, so you can do some regex manipulation for a desired output.

代码中的任何地方。如果您不喜欢它的格式,它是一个字符串数组,因此您可以对所需的输出进行一些正则表达式操作。

回答by YudhiWidyatama

How about sending signal to the ruby process, and creating a handler for the signal which dumps all stacks?

如何向 ruby​​ 进程发送信号,并为转储所有堆栈的信号创建一个处理程序?

From http://le-huy.blogspot.com/2012/04/dump-backtrace-of-all-threads-in-ruby.htmlwe have this example :

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

Then we need to send the signal to the appropriate process :

然后我们需要将信号发送到相应的进程:

ps afxw | grep ruby
kill -29 <pid>
ls -l /tmp/ruby*
vi /tmp/ruby_backtrace_...

Repeat the signal at appropriate sampling time.

在适当的采样时间重复信号。

回答by Mori

You can throw an exception at any time, and then look at the $@predefined variable, which returns an array of backtrace data. E.g. put this in foo.rb:

您可以随时抛出异常,然后查看$@预定义的变量,该变量返回一个回溯数据数组。例如把它放在 foo.rb 中:

begin                                                                        
  raise 'foo'                                                                
rescue                                                                       
  puts $@                                                                    
end  

Then run it:

然后运行它:

$ ruby foo.rb 
foo.rb:2:in `<main>'