Ответ 1
Просто поместите
puts caller
в любом месте кода. Если вам не нравится его формат, это массив строк, поэтому вы можете выполнять некоторую манипуляцию с регулярным выражением для желаемого вывода.
Я изучаю различные методы оптимизации, и я столкнулся с этим сообщением Анализ кода для эффективности? тем, кто считает, что выборка стека вызовов более эффективна, чем использование профилировщик. Основная идея заключается в том, что если вы посмотрите на стек вызовов, вы увидите, где ваше приложение, скорее всего, будет тратить большую часть своего времени, а затем оптимизировать его.
Это, безусловно, интересно, и он, очевидно, является экспертом по этому вопросу, но я не знаю, как просмотреть стек вызовов в рубине. В отладчике я могу сказать "информационный стек", но только кажется, что он показывает одну строку.
EDIT: Я видел этот комментарий Майка Данлави: "Я хотел бы отметить, что если вы запустите под отладчиком, прервите его вручную и отобразите стек вызовов..."
Я просто не уверен, как прервать его вручную и отключить стек вызовов.
Просто поместите
puts caller
в любом месте кода. Если вам не нравится его формат, это массив строк, поэтому вы можете выполнять некоторую манипуляцию с регулярным выражением для желаемого вывода.
Вы можете в любое время исключить исключение, а затем просмотреть предопределенную переменную [email protected]
, которая возвращает массив данных backtrace. Например. поместите это в foo.rb:
begin
raise 'foo'
rescue
puts [email protected]
end
Затем запустите его:
$ ruby foo.rb
foo.rb:2:in `<main>'
Как насчет отправки сигнала в рубиновый процесс и создания обработчика сигнала, который сбрасывает все стеки?
Из 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_...
Повторите сигнал при соответствующем времени выборки.