Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
638 views
in Technique[技术] by (71.8m points)

ruby - How to get a backtrace from a SystemStackError: stack level too deep?

Often I get hard to debug infinite recursions when coding ruby. Is there a way to get a backtrace out of a SystemStackError to find out, where exactly the infinite loop occurs?

Example

Given some methods foo, bar and baz which call each other in a loop:

def foo
  bar
end

def bar
  baz
end

def baz
  foo
end

foo

When I run this code, I just get the message test.rb:6: stack level too deep (SystemStackError). It would be useful to get at least the last 100 lines of the stack, so I could immediately see this is a loop between foo, bar and baz, like this:

test.rb:6: stack level too deep (SystemStackError)
  test.rb:2:in `foo'
  test.rb:10:in `baz'
  test.rb:6:in `bar'
  test.rb:2:in `foo'
  test.rb:10:in `baz'
  test.rb:6:in `bar'
  test.rb:2:in `foo'
  [...]

Is there any way to accomplish this?

EDIT:

As you may see from the answer below, Rubinius can do it. Unfortunately some rubinius bugs prevent me from using it with the software I'd like to debug. So to be precise the question is:

How do I get a backtrace with MRI (the default ruby) 1.9?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Another method for those finding this question later... An excellent gist provides instructions on enabling a trace function in the console and printing all function calls to a file. Just tested on 1.9.3-p194 and it worked great.

Including here in case the gist goes away someday:

$enable_tracing = false
$trace_out = open('trace.txt', 'w')

set_trace_func proc { |event, file, line, id, binding, classname|
  if $enable_tracing && event == 'call'
    $trace_out.puts "#{file}:#{line} #{classname}##{id}"
  end
}

$enable_tracing = true
a_method_that_causes_infinite_recursion_in_a_not_obvious_way()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...