[ruby-dev:48812] [ruby-trunk - Bug #10689] `unexpected break' occurs when TracePoint#binding is called
From:
kazuki@...
Date:
2015-01-11 07:37:46 UTC
List:
ruby-dev #48812
Issue #10689 has been updated by Kazuki Tsujimoto.
vm_throw_start内にあるflagが立っている場合の処理は
以下のように整理できるんじゃないかと思うのですがどうでしょう。
~~~diff
diff --git a/vm.c b/vm.c
index 45734e1..80b3bbe 100644
--- a/vm.c
+++ b/vm.c
@@ -1523,7 +1523,7 @@ vm_exec(rb_thread_t *th)
}
}
}
- else if (state == TAG_BREAK && ((VALUE)escape_cfp & ~0x01) == 0) {
+ else if (state == TAG_BREAK && !escape_cfp) {
type = CATCH_TYPE_BREAK;
search_restart_point:
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 05b8d15..744bbfd 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -600,8 +600,8 @@ vm_throw_start(rb_thread_t * const th, rb_control_frame_t * const reg_cfp, int s
rb_control_frame_t *escape_cfp = NULL;
const rb_control_frame_t * const eocfp = RUBY_VM_END_CONTROL_FRAME(th); /* end of control frame pointer */
- if (flag != 0) { /* TODO: memo */
- escape_cfp = (void *) 0x01;
+ if (flag != 0) {
+ /* do nothing */
}
else if (state == TAG_BREAK) {
int is_orphan = 1;
~~~
----------------------------------------
Bug #10689: `unexpected break' occurs when TracePoint#binding is called
https://bugs.ruby-lang.org/issues/10689#change-50927
* Author: Kazuki Tsujimoto
* Status: Open
* Priority: Normal
* Assignee:
* Category: core
* Target version:
* ruby -v: ruby 2.3.0dev (2015-01-02 trunk 49102) [x86_64-linux]
* Backport: 2.0.0: REQUIRED, 2.1: REQUIRED, 2.2: REQUIRED
----------------------------------------
以下のコードでunexpected breakになります。
~~~ruby
class Bug
include Enumerable
def each
[0].each do
yield
end
end
end
TracePoint.trace(:c_return) do |tp|
tp.binding
end
Bug.new.all? { false }
~~~
all?中のrb_iter_breakによってth->errinfoがセットされた後に、
TracePoint#binding呼び出しによってcfpのepがヒープを指すようになってしまうのが原因です。
とりあえずTracePoint呼び出し後にth->errinfoのepを書き換えるようにしてみたパッチを添付します。
---Files--------------------------------
fix-unexpected-break.patch (3.32 KB)
save-target-cfp-in-errinfo.patch (6.26 KB)
--
https://bugs.ruby-lang.org/