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
How about sending signal to the ruby process, and creating a handler for the signal which dumps all stacks?
From http://le-huy.blogspot.com/2012/04/dump-backtrace-of-all-threads-in-ruby.html we have this example :
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.
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.
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:
begin
raise 'foo'
rescue
puts $@
end
Then run it:
$ ruby foo.rb
foo.rb:2:in `<main>'