【问题标题】:How to get a stack trace object in Ruby?如何在 Ruby 中获取堆栈跟踪对象?
【发布时间】:2011-04-19 06:05:09
【问题描述】:

我需要在 Ruby 中获取堆栈跟踪对象;不打印它,只是为了让它做一些记录和转储以供以后分析。那可能吗?怎么样?

【问题讨论】:

    标签: ruby stack stack-trace


    【解决方案1】:

    试试error.backtrace:

    # Returns any backtrace associated with the exception.  
    # The backtrace is an array of strings, each containing either ``filename:lineNo: in `method’’’ or ``filename:lineNo.’‘
    
    def a
      raise "boom"
    end
    
    def b
      a()
    end
    
    begin
      b()
    rescue => detail
      print detail.backtrace.join("\n")
    end
    

    产生:

    prog.rb:2:in `a'
    prog.rb:6:in `b'
    prog.rb:10
    

    【讨论】:

    • 我想我必须抛出异常才能获得堆栈跟踪。
    • @J.巴勃罗 似乎如此。如果您找到直接获取的方法,请在此处发布。
    • Sven 用 Kernel.caller 搞定了。
    【解决方案2】:

    您可以为此使用Kernel.caller。为异常生成堆栈跟踪时使用相同的方法。

    来自文档:

    def a(skip)
      caller(skip)
    end
    def b(skip)
      a(skip)
    end
    def c(skip)
      b(skip)
    end
    c(0) #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10"]
    c(1) #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11"]
    c(2) #=> ["prog:8:in `c'", "prog:12"]
    c(3) #=> ["prog:13"]
    

    【讨论】:

      【解决方案3】:

      如果您愿意,您也可以创建自己的。正如 Russ Olsen 在 Eloquent Ruby 中所展示的那样:

      # define a proc to use that will handle your trace 
      proc_object = proc do |event, file, line, id, binding, klass| 
        puts "#{event} in #{file}/#{line} #{id} #{klass}"
      end 
      
      # tell Ruby to use your proc on traceable events
      set_trace_func(proc_object)
      

      【讨论】:

        【解决方案4】:

        试试

        Thread.current.backtrace.join("\n")
        

        【讨论】:

          【解决方案5】:

          对于 Ruby 2.0+,您可以使用Kernel#caller_locations。它与Kernel#caller 基本相同(在Sven Koschnicke's answer 中介绍),不同之处在于它不是返回一个字符串数组,而是返回一个Thread::Backtrace::Location 对象数组。 Thread::Backtrace::Location 提供了诸如pathlinenobase_label 之类的方法,当您需要访问有关堆栈跟踪的特定详细信息而不仅仅是原始字符串时,这些方法可能很有用。

          来自the docs

          caller_locations(start=1, length=nil) → 数组或 nil

          caller_locations(range) → 数组或 nil

          返回当前执行堆栈——一个包含回溯的数组 位置对象。

          更多信息请参见Thread::Backtrace::Location

          可选的start参数决定了初始栈的个数 要从堆栈顶部省略的条目。

          第二个可选的length 参数可用于限制多少 条目从堆栈中返回。

          如果start 大于当前执行的大小,则返回nil 堆栈。

          您可以选择传递一个范围,该范围将返回一个包含 指定范围内的条目。

          使用示例:

          def a
            caller_locations(0)
          end
          def b
            a
          end
          def c
            b
          end
          
          c.map(&:base_label)
          #=> ["a", "b", "c", "<main>"]
          

          【讨论】:

            【解决方案6】:
            Thread.current.backtrace
            

            这将为您提供一个数组,其中包含您在任何正常回溯中可能获得的所有行。

            【讨论】:

              猜你喜欢
              • 2010-10-11
              • 2010-09-11
              • 2010-12-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多