programing tip

루비가 잘린 것이 아니라 전체 역 추적을 인쇄하도록하려면 어떻게해야합니까?

itbloger 2020. 6. 12. 21:48
반응형

루비가 잘린 것이 아니라 전체 역 추적을 인쇄하도록하려면 어떻게해야합니까?


예외가 발생하면 종종 호출 스택 내부에서 발생합니다. 이런 일이 발생하는 경우, 종종 실제 코드 위반이 숨겨집니다.

tmp.rb:7:in `t': undefined method `bar' for nil:NilClass (NoMethodError)
        from tmp.rb:10:in `s'
        from tmp.rb:13:in `r'
        from tmp.rb:16:in `q'
        from tmp.rb:19:in `p'
        from tmp.rb:22:in `o'
        from tmp.rb:25:in `n'
        from tmp.rb:28:in `m'
        from tmp.rb:31:in `l'
         ... 8 levels...
        from tmp.rb:58:in `c'
        from tmp.rb:61:in `b'
        from tmp.rb:64:in `a'
        from tmp.rb:67

"... 8 레벨 ..."잘림으로 인해 많은 문제가 발생했습니다. 나는 이것에 대한 인터넷 검색에별로 성공하지 못했습니다. 루비에게 덤프에 전체 스택을 포함시키고 싶다고 어떻게 말합니까?


예외 # backtrace에는 전체 스택이 있습니다.

def do_division_by_zero
    x = 5 / 0
end
begin
    do_division_by_zero
rescue => Exception
    puts Exception.backtrace
    raise # always reraise
end          

(Peter Cooper의 Ruby Inside 블로그 에서 영감을 받음 )


간단한 원 라이너를 원한다면이 작업을 수행 할 수도 있습니다.

puts caller

이렇게하면 오류 설명과 깔끔하고 들여 쓰기 된 스택 추적이 생성됩니다.

begin               
 # Some exception throwing code
rescue => e
  puts "Error during processing: #{$!}"
  puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
end

IRB에는이 끔찍한 "기능"에 대한 설정이 있으며이를 사용자 지정할 수 있습니다.

~/.irbrc다음 행을 포함 하는 파일을 작성하십시오 .

IRB.conf[:BACK_TRACE_LIMIT] = 100

이를 통해 irb적어도 100 개의 스택 프레임을 볼 수 있습니다 . 비 대화식 런타임에 해당하는 설정을 찾을 수 없습니다.

IRB 사용자 정의에 대한 자세한 정보는 Pickaxe 서적 에서 찾을 수 있습니다 .


콜 스택을위한 하나의 라이너 :

begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace; end

모든 보석이없는 콜스 택용 라이너 :

begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace.grep_v(/\/gems\//); end

모든 gem이없고 현재 디렉토리에 상대적인 콜 스택을위한 하나의 라이너

begin; Whatever.you.want; rescue => e; puts e.message; puts; puts e.backtrace.grep_v(/\/gems\//).map { |l| l.gsub(`pwd`.strip + '/', '') }; end

중요한 루비 추적을 모방합니다.

begin
  0/0  # or some other nonsense
rescue => e
  puts e.backtrace.join("\n\t")
       .sub("\n\t", ": #{e}#{e.class ? " (#{e.class})" : ''}\n\t")
end

흥미롭게도 '처리되지 않은 예외'를 올바르게 처리하지 않아 'RuntimeError'로보고되지만 위치는 정확합니다.


I was getting these errors when trying to load my test environment (via rake test or autotest) and the IRB suggestions didn't help. I ended up wrapping my entire test/test_helper.rb in a begin/rescue block and that fixed things up.

begin
  class ActiveSupport::TestCase
    #awesome stuff
  end
rescue => e
  puts e.backtrace
end

[examine all threads backtraces to find the culprit]
Even fully expanded call stack can still hide the actual offending line of code from you when you use more than one thread!

Example: One thread is iterating ruby Hash, other thread is trying to modify it. BOOM! Exception! And the problem with the stack trace you get while trying to modify 'busy' hash is that it shows you chain of functions down to the place where you're trying to modify hash, but it does NOT show who's currently iterating it in parallel (who owns it)! Here's the way to figure that out by printing stack trace for ALL currently running threads. Here's how you do this:

# This solution was found in comment by @thedarkone on https://github.com/rails/rails/issues/24627
rescue Object => boom

    thread_count = 0
    Thread.list.each do |t|
      thread_count += 1
      err_msg += "--- thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace begin \n"
      # Lets see if we are able to pin down the culprit
      # by collecting backtrace for all existing threads:
      err_msg += t.backtrace.join("\n")
      err_msg += "\n---thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace end \n"
    end

    # and just print it somewhere you like:
    $stderr.puts(err_msg)

    raise # always reraise
end

The above code snippet is useful even just for educational purposes as it can show you (like x-ray) how many threads you actually have (versus how many you thought you have - quite often those two are different numbers ;)


You can also use backtrace Ruby gem (I'm the author):

require 'backtrace'
begin
  # do something dangerous
rescue StandardError => e
  puts Backtrace.new(e)
end

참고URL : https://stackoverflow.com/questions/376513/how-do-i-get-ruby-to-print-a-full-backtrace-instead-of-a-truncated-one

반응형