From: Rocky Bernstein Date: 2010-03-17T20:42:18+09:00 Subject: [ruby-core:28712] When a trace hook raises an exception, should it terminate the program? --00504502aef12359240481fd9b3d Content-Type: text/plain; charset=ISO-8859-1 In Ruby 1.8 and the Ruby 1.9 trunk when running a trace hook that raises an exception not caught by the hook, the program terminates -- whether or not there is a rescue further up the call stack, i.e. in the non-hook body. Ruby 1.9 also gives a stack trace, while Ruby 1.8 doesn't. How do JRuby, IronRuby and Rubinius and other Rubies handle this? And what do the specifications say? If it is the case that raising an exception in a trace hook unconditionally terminates the hooked program, programmers that want to write a trace hook that plays nice with programs it hooks against should wrap the hook in a begin/rescue block. Or make sure your code never raises an uncaught exception. Here is some test code followed by output: s = Proc.new { # line 1 |event, file, lineno, mid, binding, klass| # line 2 puts "#{event} #{mid} :#{lineno}" # line 3 raise RuntimeError # line 4 } # line 5 begin # line 6 set_trace_func(s) # line 7 puts "after trace func" # line 8 rescue # line 9 puts "Rescued" # line 10 end # line 11 For Ruby 1.8.7 2009-07-12 patchlevel 174: $ /usr/bin/ruby trace-bug.rb line trace-bug.rb:8 line trace-bug.rb:10 c-call backtrace trace-bug.rb:10 c-call write trace-bug.rb:10 For Ruby 1.9 trunk (Rev 26961): $ ./ruby trace-bug.rb c-return set_trace_func trace-bug.rb:7 c-call === trace-bug.rb:10 trace-bug.rb:4:in `block in
': RuntimeError (RuntimeError) from trace-bug.rb:10:in `rescue in
' from trace-bug.rb:6:in `
' By the way, also note that Ruby 1.9 includes as a trace event the C return from set_trace_func. I find this not quite right. In a patch to an experimental Ruby to add better debugging support, this event is removed. I'll open a ticket in Redmine if it is decided this is something worth reporting. Thanks. --00504502aef12359240481fd9b3d Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable In Ruby 1.8 and the Ruby 1.9 trunk when running a trace hook that raises an= exception not caught by the hook, the program terminates -- whether or not= there is a rescue further up the call stack, i.e. in the non-hook body.
Ruby 1.9 also gives a stack trace, while Ruby 1.8 doesn't.

= How do JRuby, IronRuby and Rubinius and other Rubies handle this? And what = do the specifications say?

If it is the case that raising an except= ion in a trace hook unconditionally terminates the hooked program, programm= ers that want to write a trace hook that plays nice with programs it hooks = against should wrap the hook in a begin/rescue block. Or make sure your cod= e never raises an uncaught exception.

Here is some test code followed by output:

s =3D Proc.new {=A0 #= line 1
=A0 |event, file, lineno, mid, binding, klass|=A0 # line 2
= =A0 puts "#{event} #{mid} :#{lineno}"=A0=A0 # line 3
=A0 raise= RuntimeError=A0=A0 # line 4
}=A0=A0 # line 5
begin=A0=A0 # line 6
=A0 set_trace_func(s)=A0=A0 # l= ine 7
=A0 puts "after trace func"=A0 # line 8
rescue=A0=A0 = # line 9
=A0 puts "Rescued"=A0 # line 10
end=A0=A0 # line 1= 1


For Ruby 1.8.7 2009-07-12 patchlevel 174:

$ /usr/bin/ruby trace-bug.= rb
line=A0 trace-bug.rb:8
line=A0 trace-bug.rb:10
c-call backtrace= trace-bug.rb:10
c-call write trace-bug.rb:10

For Ruby 1.9 trunk (Rev 26961):

$ ./ruby trace-bug.rb
c-return se= t_trace_func trace-bug.rb:7
c-call =3D=3D=3D trace-bug.rb:10
trace-bu= g.rb:4:in `block in <main>': RuntimeError (RuntimeError)
=A0= =A0=A0 from trace-bug.rb:10:in `rescue in <main>'
=A0=A0=A0 from trace-bug.rb:6:in `<main>'

By the way, also= note that Ruby 1.9 includes as a trace event the C return from set_trace_f= unc. I find this not quite right. In a patch to an experimental Ruby to add= better debugging support, this event is removed.

I'll open a ticket in Redmine if it is decided this is something wo= rth reporting.

Thanks.

=A0







--00504502aef12359240481fd9b3d--