From: Yusuke ENDOH Date: 2008-10-21T20:12:26+09:00 Subject: [ruby-dev:36847] Re: abort in rescue 遠藤です。 この件、反応をお願いします。 > ささださん 2008/10/13 17:41 Yusuke ENDOH : > 遠藤です。 > > 1.8 では rescue の中で abort するとスタックトレースを出すようですが、 > 1.9 では何も表示されなくなっています。 > > > $ ruby18 -e 'begin; raise; rescue; abort; end' > -e:1: unhandled exception > > $ ruby19 -e 'begin; raise; rescue; abort; end' > > > rb_f_abort を見るとスタックトレースを出そうとするコードが残っており、 > 意図的な挙動変更には見えませんでした。 > > スタックトレースを出すようにするのは簡単ですが、1.9 では $! = nil が > 禁止されているため、この挙動を抑止する方法がありません。 > > > $ ruby18 -e 'begin; raise; rescue; $! = nil; abort; end' > > $ ruby19 -e 'begin; raise; rescue; $! = nil; abort; end' > -e:1:in `rescue in
': $! is a read-only variable (NameError) > from -e:1:in `
' > > > どうしたもんでしょうか。 > 以下はスタックトレースを出すようにし、$! への代入を許可するように > するパッチです。 > > > Index: eval.c > =================================================================== > --- eval.c (revision 19769) > +++ eval.c (working copy) > @@ -426,7 +426,7 @@ > rb_raise(rb_eInterrupt, "%s", ""); > } > > -static VALUE get_errinfo(void); > +VALUE get_errinfo(void); > > /* > * call-seq: > @@ -953,7 +953,7 @@ > return 0; > } > > -static VALUE > +VALUE > get_errinfo(void) > { > VALUE *ptr = errinfo_place(); > @@ -971,7 +971,6 @@ > return get_errinfo(); > } > > -#if 0 > static void > errinfo_setter(VALUE val, ID id, VALUE *var) > { > @@ -988,7 +987,6 @@ > } > } > } > -#endif > > VALUE > rb_errinfo(void) > @@ -1119,7 +1117,7 @@ > Init_eval(void) > { > rb_define_virtual_variable("$@", errat_getter, errat_setter); > - rb_define_virtual_variable("$!", errinfo_getter, 0); > + rb_define_virtual_variable("$!", errinfo_getter, errinfo_setter); > > rb_define_global_function("iterator?", rb_f_block_given_p, 0); > rb_define_global_function("block_given?", rb_f_block_given_p, 0); > Index: process.c > =================================================================== > --- process.c (revision 19769) > +++ process.c (working copy) > @@ -2534,10 +2534,12 @@ > rb_f_abort(int argc, VALUE *argv) > { > extern void ruby_error_print(void); > + extern VALUE get_errinfo(void); > > rb_secure(4); > if (argc == 0) { > - if (!NIL_P(GET_THREAD()->errinfo)) { > + VALUE errinfo = GET_THREAD()->errinfo = get_errinfo(); > + if (!NIL_P(errinfo)) { > ruby_error_print(); > } > rb_exit(EXIT_FAILURE); > > -- > Yusuke ENDOH > > -- Yusuke ENDOH