Not swallowed levels of the backtrace on unrescued exception


#1

Currently ruby [at least versions 1.8.6 and greater]
swallows the “middle” of backtraces if the thrown error was
“SystemStackError”:
ex:

cat bad.rb
def go
go2
end

def go2
go
end
go

ruby bad.rb
bad.rb:5:in go2': stack level too deep (SystemStackError) from bad.rb:2:ingo’
from bad.rb:5:in go2' from bad.rb:2:ingo’
from bad.rb:5:in go2' from bad.rb:2:ingo’
from bad.rb:5:in go2' from bad.rb:2:ingo’
from bad.rb:5:in go2' ... 22112 levels... from bad.rb:2:ingo’
from bad.rb:5:in go2' from bad.rb:2:ingo’
from bad.rb:8

However, this has the unfortunate side effect of preventinf useful parts
of the backtrace from being displayed in certain other cases, here’s an
example I ran into just recently:

C:/dev/ruby-benchmark-suite/rails/substruct/vendor/plugins/attachment_fu_fixtures/lib/attachment_fu_fixtures.rb:53:in
include?': stack level too deep (SystemStackError) from C:/dev/ruby-benchmark-suite/rails/substruct/vendor/plugins/attachment_fu_fixtures/lib/attachment_fu_fixtures.rb:53:inattachment_model?’
from
C:/dev/ruby-benchmark-suite/rails/substruct/vendor/plugins/attachment_fu_fixtures/lib/attachment_fu_fixtures.rb:10:in
insert_fixture_without_attachment' from C:/dev/ruby-benchmark-suite/rails/substruct/vendor/plugins/attachment_fu_fixtures/lib/attachment_fu_fixtures.rb:28:ininsert_fixture’
from
C:/dev/ruby-benchmark-suite/rails/substruct/vendor/rails/activerecord/lib/active_record/fixtures.rb:639:in
insert_fixtures' from C:/dev/ruby-benchmark-suite/rails/substruct/vendor/rails/activerecord/lib/active_record/fixtures.rb:576:ineach’
from
C:/dev/ruby-benchmark-suite/rails/substruct/vendor/rails/activerecord/lib/active_record/fixtures.rb:576:in
insert_fixtures' from C:/dev/ruby-benchmark-suite/rails/substruct/vendor/rails/activerecord/lib/active_record/fixtures.rb:520:increate_fixtures’
from
C:/dev/ruby-benchmark-suite/rails/substruct/vendor/rails/activerecord/lib/active_record/fixtures.rb:520:in
each' ... 24 levels... from c:/ruby18/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:564:ininvoke’
from ./substruct_start_and_bootstrap_if_necessary.rb:15
from bm_substruct_request_root_100x.rb:8:in `require’
from bm_substruct_request_root_100x.rb:8

So my question is:
What would be a better way to handle this in core [I want to submit a patch, but am unsure what would be better].
some possibilities: if $VERBOSE is set then output all levels.
Have it output “100 lines” of backtrace each time–probably enough.

Thoughts?
-=r


#2

On Sat, 07 Feb 2009 10:51:23 -0500, Roger P. wrote:

def go
go2
end

def go2
go
end
go

def go
go2
end

def go2
go
end

begin
go
rescue StandardError => e
require ‘pp’
pp e.backtrace
end

will print all the levels, so what you should probably do is submit a
patch to Rails or Rake to explicitly catch the exception and customize
the output (possibly by grepping out things internal to rails and rake,
or by printing more levels there.)

–Ken