Ruby 怎么样打印一下 ruby 的运行栈?

jimrokliu · 2013年11月20日 · 最后由 tumayun 回复于 2013年11月21日 · 5692 次阅读

写了一个 rake 处理系统的数据,不知道在什么地方挂住了。搜索了一下方法都比较旧,针对 1.8 的,我用的环境是 1.9.3。这个有什么 gem 吗?我需要 kill -3 1234,这样控制台就能打印出来系统的运行栈,输出到 dump 文件也 ok。知道的回答一下吧?

用 set_trace_func 看看能否得到有用的信息

rake --trace some_task 会比较慢,换成 Ruby 2.0 用 Dtrace 方法调用的话可以比较快,不过 dtrace 脚本不太好写而且要 sudo


从 C 的运行栈也有可能看出运行到哪里卡住了

gdb 1234.core
bt

还有个笨方法就是打日志

#2 楼 @luikore 找了一片 blog,用 gdb 的方法。http://rrn.dk/running-ruby-process-callstack 我的一些数据调用网络功能阻塞了。

对 gdb 的用法还不太会呢,学习

异常时的运行栈? 默认打的就足够了吧 或手动直接打

bein
  #your code
rescue Exception => e
  e.backtrace.join("\n")
end

刚刚解决了一个死锁问题,发现 newrelic_rpm gem 里有个很好用的工具,在 bin 文件夹里,叫做 nrdegub.

#5 楼 @ZombieCoder 不是在异常的时候打印。而是看看程序运行在什么地方。写了个代码加入到 initializers。

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 "--------------------------------------------------------------------"
          f.puts t.backtrace
        end
      else
          f.puts caller
      end
  end
end

Signal.trap(29) do
  backtrace_for_all_threads("INFO")
end


这样 kill -29 your_pid 就可以将运行栈输出到/tmp 目录下。

这个方法很赞

pstrace -p pid

需要 登录 后方可回复, 如果你还没有账号请 注册新账号