我正在开发使用线程的Ruby应用程序。我在调试它时遇到困难。主要问题是我想逐步浏览特定线程。我设置了断点并运行,但是直到使用thr sw 2之类的东西之前,什么都没有发生。但是随后的输入是FUBAR'd。我尝试过 pry ,但是 pry 似乎在处理线程方面并不更好。

解决方案?解决方法?

编辑1:

仅供引用:Pry version 0.10.1 on Ruby 2.0.0byebug
这就是我对Pry的经验。尝试1:我使用break设置特定于线程的断点

  • 让程序运行。
  • 断点已触发。
  • pry 向我正确显示了断点和周围的代码。
  • 现在什么都没有。我没有提示。 Control-C不起作用。实际上,我必须从外部 kill -9进程。

  • 尝试2:使用上面的“binding.pry”方法。
  • 相同
  • 相同
  • 一样!
  • 我得到一个 pry 提示!我可以产生表达式。
  • 我尝试使用“step”或“next”,突然我进入“Pry::history#load”。因此,现在调试器已跳到正在处理输入本身的线程。这不起作用。

  • pry 输出:
    [2] pry(#<QDS::Node::Primary>)> 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(#<Pry::History>)>
    
  • 我尝试“退出”,现在我处于“ pry (主)”状态,而没有其他任何工作。

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

    最佳答案

    pry与线程一起工作就可以了。您的代码中可能存在故障。

    让我们尝试检查以下线程切换器(示例为here):

    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
    => #<Mutex:0xb21f204>
    ▶ 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恢复为止。

    关于ruby - 调试线程 ruby 应用程序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29646434/

    10-13 04:05