From: Charles Oliver Nutter Date: 2010-03-19T03:37:28+09:00 Subject: [ruby-core:28763] Re: When a trace hook raises an exception, should it terminate the program? On Thu, Mar 18, 2010 at 5:52 AM, Rocky Bernstein wrote: > The "sort of" part is�� that in Ruby 1.9 the implementation of tracing sets a > bit in the thread structure which turns off tracing into the tracer (or > debugging into the debugger). When an exception that passes from hook to > non-hook occurs, this bit doesn't get cleared. That doesn't appear to be the case in JRuby. The bit clearing happens in a Java "finally" block, which runs no matter what happens in the hook itself. See below. > Changing the program that was originally posted will show this better: > > s = Proc.new { > �� |event, file, lineno, mid, binding, klass| > �� puts "#{event} #{mid} #{lineno}" > �� unless $x > ������ $x = true > ������ raise RuntimeError > �� end > } > begin > �� set_trace_func(s) > �� puts "after trace func" > rescue > �� puts "Rescued" > end > puts "After begin" > > Run this in Ruby 1.9 and perhaps it is more apparent that the program > continues to the end. In the original posting if you look carefully you'll > see that the rescue did run *after* the trace hook issued a raise inside the > begin block. It is the *second* raise issued in the hook function that > terminates the program because the debugged program is no longer in a > rescue'd block. In the JRuby case, for your original script, it seemed to take several raises for it to terminate. All the trace events appeared to be in the main body of code, and not inside the trace hook. Here's the behavior for the new script in JRuby, which seems to continue tracing appropriately after the initial raise inside the hook ~/projects/jruby ��� jruby --debug hook_thing2.rb line 11 (first event, causes raise) c-call === 11 (rescue calling ===) c-return === 11 (=== returning) line 13 (inside rescue block) c-call puts 13 (calling puts) c-call write 13 (puts calls write) Rescuedc-return write 13 (write returns) c-call write 13 (puts calls write again for \n) c-return write 13 (write returns) c-return puts 13 (puts returns) line 15 (outside rescue block) c-call puts 15 (calling puts) c-call write 15 (puts calls write) After beginc-return write 15 (write returns) c-call write 15 (puts calls write for \n) c-return write 15 (write returns) c-return puts 15 (puts returns) Is this the output you expected? If not, what do you expect? > From what you describe from JRuby, it sounds like it has a similar behavior > possibly because it is implemented underneath in a similar way. So > rationalizing this as "this makes sense because this happened in between > statements and not in the program" I don't think is accurately capturing > what's going inside either interpreter. Your original script could never do anything but terminate because the hooks just kept re-throwing...or at least they did in JRuby, which turns tracing back on when the hook is exited, even if it's exited abnormally (because of an exception). - Charlie