diff options
author | ktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-10-21 10:14:26 +0000 |
---|---|---|
committer | ktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-10-21 10:14:26 +0000 |
commit | f21d7d98318919c730a5dbcca9f2c931ebd66898 (patch) | |
tree | 0fccea5533fff66247a7d84fa49096e2e8b058a4 | |
parent | 93184600c8dfe84f03d2c41035c5bc0fdbe4e84f (diff) | |
download | ruby-f21d7d98318919c730a5dbcca9f2c931ebd66898.tar.gz |
* vm_core.h (rb_vm_t::trace_running): add a new field
`trace_running' to store vm global tracing status.
* vm_trace.c: fix SEGV bug. event_hook was free'd
even when the hook is still used in another thread.
[ruby-dev:46141] [Bug #7032]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37280 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | vm_core.h | 1 | ||||
-rw-r--r-- | vm_trace.c | 14 |
3 files changed, 20 insertions, 4 deletions
@@ -1,3 +1,12 @@ +Sun Oct 21 19:12:59 2012 Kazuki Tsujimoto <kazuki@callcc.net> + + * vm_core.h (rb_vm_t::trace_running): add a new field + `trace_running' to store vm global tracing status. + + * vm_trace.c: fix SEGV bug. event_hook was free'd + even when the hook is still used in another thread. + [ruby-dev:46141] [Bug #7032] + Sun Oct 21 19:12:42 2012 Kazuki Tsujimoto <kazuki@callcc.net> * vm_core.h (rb_vm_t::trace_flag): remove `trace_flag' @@ -343,6 +343,7 @@ typedef struct rb_vm_struct { int running; int inhibit_thread_creation; int thread_abort_on_exception; + int trace_running; volatile int sleeper; /* object management */ diff --git a/vm_trace.c b/vm_trace.c index 90c2bd25ff..99a1d32860 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -268,12 +268,12 @@ clean_hooks(rb_hook_list_t *list) } static int -exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg) +exec_hooks(rb_thread_t *th, rb_hook_list_t *list, const rb_trace_arg_t *trace_arg, int can_clean_hooks) { int state; volatile int raised; - if (UNLIKELY(list->need_clean > 0)) { + if (UNLIKELY(list->need_clean > 0) && can_clean_hooks) { clean_hooks(list); } @@ -310,10 +310,12 @@ rb_threadptr_exec_event_hooks(rb_thread_t *th, rb_event_flag_t event, VALUE self { if (th->trace_running == 0 && self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) { + int vm_tracing = th->vm->trace_running; int state = 0; int outer_state = th->state; th->state = 0; + th->vm->trace_running = 1; th->trace_running = 1; { const VALUE errinfo = th->errinfo; @@ -330,20 +332,21 @@ rb_threadptr_exec_event_hooks(rb_thread_t *th, rb_event_flag_t event, VALUE self /* thread local traces */ list = &th->event_hooks; if (list->events & event) { - state = exec_hooks(th, list, &ta); + state = exec_hooks(th, list, &ta, TRUE); if (state) goto terminate; } /* vm global traces */ list = &th->vm->event_hooks; if (list->events & event) { - state = exec_hooks(th, list, &ta); + state = exec_hooks(th, list, &ta, !vm_tracing); if (state) goto terminate; } th->errinfo = errinfo; } terminate: th->trace_running = 0; + th->vm->trace_running = vm_tracing; if (state) { TH_JUMP_TAG(th, state); @@ -360,8 +363,10 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg) VALUE result = Qnil; rb_thread_t *th = GET_THREAD(); int state; + int vm_tracing = th->vm->trace_running; int tracing = th->trace_running; + th->vm->trace_running = 1; th->trace_running = 1; raised = rb_threadptr_reset_raised(th); outer_state = th->state; @@ -377,6 +382,7 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg) rb_threadptr_set_raised(th); } th->trace_running = tracing; + th->vm->trace_running = vm_tracing; if (state) { JUMP_TAG(state); |