调试线程ruby应用程序

我正在开发一个使用线程的ruby应用程序。 我无法调试它。 主要问题是我想逐步完成一个特定的线程。 我设置断点并运行,但在使用thr sw 2类的东西之前没有任何反应。 但后来的输入是FUBAR。 我试过撬,但撬似乎没有更好的处理线程。

解决方案? 变通?

编辑1:

仅供参考:使用byebug Pry version 0.10.1 on Ruby 2.0.0byebug Pry version 0.10.1 on Ruby 2.0.0

所以这就是我对Pry的体验。 尝试1:我使用break设置特定于线程的断点

  1. 让程序运行。
  2. 断点被触发。
  3. 撬正确地向我显示了断点和周围的代码。
  4. 什么都没有。 我没有提示 。 Control-C不起作用。 事实上,我必须从外面杀死-9这个过程。

尝试2:使用上面的“binding.pry”方法。

  1. 相同
  2. 相同
  3. 相同!
  4. 我得到了一个Pry提示! 我可以表达。
  5. 我尝试使用“步骤”或“下一步”,突然我在“Pry :: history #load”中。 所以现在调试器已跳转到正在处理输入本身的线程。 这不起作用。

撬输出:

 [2] pry(#)> step From: /usr/local/rvm/gems/ruby-2.0.0-p598/gems/pry-0.10.1/lib/pry/history.rb @ line 37 Pry::History#load: 35: def load 36: @loader.call do |line| => 37: @pusher.call(line.chomp) 38: @history << line.chomp 39: @original_lines += 1 40: end 41: end [2] pry(#)> 
  1. 我尝试“退出”,现在我在“撬(主)”没有任何其他工作。

撬输出:

 [1] pry(main)> continue Error: Cannot find local context. Did you use `binding.pry`? 

pry可以很好地处理线程。 您的代码中可能存在故障。

让我们尝试检查以下线程切换器(示例在这里采取):

 require 'pry' module SeqExec class Seqs attr_reader :init def synch_prior mx, cv Thread.new { mx.synchronize { @init[:prior] = true loop do cv.wait mx # binding.pry yield if block_given? cv.broadcast end } } end def synch_posterior mx, cv Thread.new { mx.synchronize { @init[:posterior] = true loop do cv.wait mx yield if block_given? cv.broadcast end } } end def synch λ1, λ2 @init = {} mx = Mutex.new cv = ConditionVariable.new synch_prior(mx, cv, &λ1) # prior function Thread.pass until {:prior=>true} == @init synch_posterior(mx, cv, &λ2) # posterior function Thread.pass until {:prior=>true,:posterior=>true} == @init cv.signal # we are ready to start end end end module SeqExec Thread.abort_on_exception = true def pre &cb @prior = cb end def post &cb @posterior = cb end def run λ1 = nil, λ2 = nil pre &λ1 if λ1 post &λ2 if λ2 raise ArgumentError.new "Cannot run sequential execution, lambdas are not set" \ unless (@prior && @posterior) Seqs.new.synch @prior, @posterior end end include SeqExec @i=0 @stack = [] pre { sleep 0.3; print "-#{@i += 1}-"; @stack.push(@i) } post { print "|#{@stack.pop}|" } run 10.times { sleep 0.1 } sleep 30000 

随着binding.pry注释掉,它打印出来:

 #⇒ -1-|1|-2-|2|-3-|3|-4-|4|-5-|5|-6-|6|-7-........ 

使用binding.pry取消注释,我们产生:

 Frame number: 0/2 From: /tmp/a.rb @ line 12 SeqExec::Seqs#synch_prior: 6: def synch_prior mx, cv 7: Thread.new { 8: mx.synchronize { 9: @init[:prior] = true 10: loop do 11: cv.wait mx => 12: binding.pry 13: yield if block_given? 14: cv.broadcast 15: end 16: } 17: } 18: end ▶ mx => # ▶ exit -1-|1| Frame number: 0/2 From: /tmp/a.rb @ line 12 SeqExec::Seqs#synch_prior: 6: def synch_prior mx, cv 7: Thread.new { 8: mx.synchronize { 9: @init[:prior] = true 10: loop do 11: cv.wait mx => 12: binding.pry 13: yield if block_given? 14: cv.broadcast 15: end 16: } 17: } 18: end ▶ exit -2-|2| Frame number: 0/2 ... 

不用说,上述意味着线程停止直到pry恢复。