[ruby-dev:48299] [ruby-trunk - Bug #9961] [Open] TracePoint can skip c_return with rb_rescue()
From:
ko1@...
Date:
2014-06-19 12:40:54 UTC
List:
ruby-dev #48299
Issue #9961 has been reported by Koichi Sasada.
----------------------------------------
Bug #9961: TracePoint can skip c_return with rb_rescue()
https://bugs.ruby-lang.org/issues/9961
* Author: Koichi Sasada
* Status: Open
* Priority: Normal
* Assignee: Koichi Sasada
* Category: core
* Target version: current: 2.2.0
* ruby -v: 2.2
* Backport: 2.0.0: REQUIRED, 2.1: REQUIRED
----------------------------------------
=E4=B8=8B=E8=A8=98=E3=81=AE=E3=82=88=E3=81=86=E3=81=AA=E3=83=86=E3=82=B9=E3=
=83=88=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=97=E3=81=BE=E3=81=99=E3=80=82
```ruby
def test_rb_rescue
events =3D []
curr_thread =3D Thread.current
TracePoint.new(:a_call, :a_return){|tp|
next if curr_thread !=3D Thread.current
events << [tp.event, tp.method_id]
}.enable do
begin
-Numeric.new
rescue =3D> e
# ignore
end
end
assert_equal [
[:b_call, :test_rb_rescue],
[:c_call, :new],
[:c_call, :initialize],
[:c_return, :initialize],
[:c_return, :new],
[:c_call, :-@],
[:c_call, :coerce],
[:c_call, :to_s],
[:c_return, :to_s],
[:c_call, :new],
[:c_call, :initialize],
[:c_return, :initialize],
[:c_return, :new],
[:c_call, :exception],
[:c_return, :exception],
[:c_call, :backtrace],
[:c_return, :backtrace],
[:c_return, :coerce], # don't miss it!
[:c_call, :to_s],
[:c_return, :to_s],
[:c_call, :to_s],
[:c_return, :to_s],
[:c_call, :new],
[:c_call, :initialize],
[:c_return, :initialize],
[:c_return, :new],
[:c_call, :exception],
[:c_return, :exception],
[:c_call, :backtrace],
[:c_return, :backtrace],
[:c_return, :-@],
[:c_call, :=3D=3D=3D],
[:c_return, :=3D=3D=3D],
[:b_return, :test_rb_rescue]], events
end
```
=E4=BD=95=E3=81=8C=E8=B5=B7=E3=81=8D=E3=81=A6=E3=81=84=E3=82=8B=E3=81=8B=E3=
=81=A8=E3=81=84=E3=81=86=E3=81=A8=E3=80=81
(1) -Numeric.new =E3=81=A7 rb_rescue() =E3=81=AE=E5=BE=8C=E3=81=A7 rb_funca=
ll() =E3=81=97=E3=81=9F=E5=85=88=E3=81=A7=E4=BE=8B=E5=A4=96=E3=81=8C=E8=B5=
=B7=E3=81=93=E3=82=8B
(2) rb_rescue() =E3=81=A7=E3=81=AF=E3=80=81c_return =E3=82=92=E7=84=A1=E8=
=A6=96=E3=81=97=E3=81=A6 cfp =E3=82=92=E5=88=87=E3=82=8A=E8=A9=B0=E3=82=81=
=E3=82=8B
=E3=81=A8=E3=81=84=E3=81=86=E3=81=93=E3=81=A8=E3=81=AB=E3=82=88=E3=82=8A=E3=
=80=81c_return =E3=81=8C=E3=82=B9=E3=82=AD=E3=83=83=E3=83=97=E3=81=97=E3=81=
=A6=E3=81=97=E3=81=BE=E3=81=86=E3=80=81=E3=81=A8=E3=81=84=E3=81=86=E7=8F=BE=
=E8=B1=A1=E3=81=A8=E3=81=AA=E3=82=8A=E3=81=BE=E3=81=97=E3=81=9F=E3=80=82
=E6=AC=A1=E3=81=AE=E3=83=91=E3=83=83=E3=83=81=E3=81=A7=E8=A7=A3=E6=B1=BA=E3=
=81=97=E3=81=BE=E3=81=99=E3=80=82
```diff
Index: eval.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- eval.c (revision 46464)
+++ eval.c (working copy)
@@ -803,7 +803,7 @@ rb_rescue2(VALUE (* b_proc) (ANYARGS), V
}
}
else {
- th->cfp =3D cfp; /* restore */
+ rb_vm_rewind_cfp(th, cfp);
=20
if (state =3D=3D TAG_RAISE) {
int handle =3D FALSE;
@@ -862,7 +862,7 @@ rb_protect(VALUE (* proc) (VALUE), VALUE
SAVE_ROOT_JMPBUF(th, result =3D (*proc) (data));
}
else {
- th->cfp =3D cfp;
+ rb_vm_rewind_cfp(th, cfp);
}
MEMCPY(&(th)->root_jmpbuf, &org_jmpbuf, rb_jmpbuf_t, 1);
th->protect_tag =3D protect_tag.prev;
Index: vm.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm.c (revision 46464)
+++ vm.c (working copy)
@@ -288,6 +288,23 @@ rb_vm_pop_cfunc_frame(void)
vm_pop_frame(th);
}
=20
+void
+rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+ /* check skipped frame */
+ while (th->cfp !=3D cfp) {
+#if VMDEBUG
+ printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
+#endif
+ if (VM_FRAME_TYPE(th->cfp) !=3D VM_FRAME_MAGIC_CFUNC) {
+ vm_pop_frame(th);
+ }
+ else { /* unlikely path */
+ rb_vm_pop_cfunc_frame();
+ }
+ }
+}
+
/* obsolete */
void
rb_frame_pop(void)
Index: vm_core.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm_core.h (revision 46464)
+++ vm_core.h (working copy)
@@ -901,6 +901,7 @@ VALUE rb_name_err_mesg_new(VALUE obj, VA
void rb_vm_stack_to_heap(rb_thread_t *th);
void ruby_thread_init_stack(rb_thread_t *th);
int rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *id=
p, VALUE *klassp);
+void rb_vm_rewind_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
=20
void rb_gc_mark_machine_stack(rb_thread_t *th);
=20
Index: vm_eval.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- vm_eval.c (revision 46464)
+++ vm_eval.c (working copy)
@@ -1093,18 +1093,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VA
th->errinfo =3D Qnil;
retval =3D GET_THROWOBJ_VAL(err);
=20
- /* check skipped frame */
- while (th->cfp !=3D cfp) {
-#if VMDEBUG
- printf("skipped frame: %s\n", vm_frametype_name(th->cfp));
-#endif
- if (VM_FRAME_TYPE(th->cfp) !=3D VM_FRAME_MAGIC_CFUNC) {
- vm_pop_frame(th);
- }
- else { /* unlikely path */
- rb_vm_pop_cfunc_frame();
- }
- }
+ rb_vm_rewind_cfp(th, cfp);
}
else{
/* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
```
=E4=BE=8B=E3=81=AB=E3=82=88=E3=81=A3=E3=81=A6=E3=80=812.1, 2.0 =E3=81=A7=E3=
=82=82=E3=81=8A=E3=81=8D=E3=81=BE=E3=81=99=E3=80=82
=EF=BC=88Numeric.new =E3=81=AA=E3=82=93=E3=81=A6=E3=81=A7=E3=81=8D=E3=82=8B=
=E3=81=A8=E3=81=AF=E7=9F=A5=E3=82=89=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=EF=
=BC=89
--=20
https://bugs.ruby-lang.org/