From f21d7d98318919c730a5dbcca9f2c931ebd66898 Mon Sep 17 00:00:00 2001 From: ktsj Date: Sun, 21 Oct 2012 10:14:26 +0000 Subject: * 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 --- vm_trace.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'vm_trace.c') 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); -- cgit v1.2.3