1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
ktsj 2012-10-21 10:14:26 +00:00
parent 93184600c8
commit f21d7d9831
3 changed files with 20 additions and 4 deletions

View file

@ -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> Sun Oct 21 19:12:42 2012 Kazuki Tsujimoto <kazuki@callcc.net>
* vm_core.h (rb_vm_t::trace_flag): remove `trace_flag' * vm_core.h (rb_vm_t::trace_flag): remove `trace_flag'

View file

@ -343,6 +343,7 @@ typedef struct rb_vm_struct {
int running; int running;
int inhibit_thread_creation; int inhibit_thread_creation;
int thread_abort_on_exception; int thread_abort_on_exception;
int trace_running;
volatile int sleeper; volatile int sleeper;
/* object management */ /* object management */

View file

@ -268,12 +268,12 @@ clean_hooks(rb_hook_list_t *list)
} }
static int 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; int state;
volatile int raised; volatile int raised;
if (UNLIKELY(list->need_clean > 0)) { if (UNLIKELY(list->need_clean > 0) && can_clean_hooks) {
clean_hooks(list); 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 && if (th->trace_running == 0 &&
self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) { self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
int vm_tracing = th->vm->trace_running;
int state = 0; int state = 0;
int outer_state = th->state; int outer_state = th->state;
th->state = 0; th->state = 0;
th->vm->trace_running = 1;
th->trace_running = 1; th->trace_running = 1;
{ {
const VALUE errinfo = th->errinfo; 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 */ /* thread local traces */
list = &th->event_hooks; list = &th->event_hooks;
if (list->events & event) { if (list->events & event) {
state = exec_hooks(th, list, &ta); state = exec_hooks(th, list, &ta, TRUE);
if (state) goto terminate; if (state) goto terminate;
} }
/* vm global traces */ /* vm global traces */
list = &th->vm->event_hooks; list = &th->vm->event_hooks;
if (list->events & event) { if (list->events & event) {
state = exec_hooks(th, list, &ta); state = exec_hooks(th, list, &ta, !vm_tracing);
if (state) goto terminate; if (state) goto terminate;
} }
th->errinfo = errinfo; th->errinfo = errinfo;
} }
terminate: terminate:
th->trace_running = 0; th->trace_running = 0;
th->vm->trace_running = vm_tracing;
if (state) { if (state) {
TH_JUMP_TAG(th, state); TH_JUMP_TAG(th, state);
@ -360,8 +363,10 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg)
VALUE result = Qnil; VALUE result = Qnil;
rb_thread_t *th = GET_THREAD(); rb_thread_t *th = GET_THREAD();
int state; int state;
int vm_tracing = th->vm->trace_running;
int tracing = th->trace_running; int tracing = th->trace_running;
th->vm->trace_running = 1;
th->trace_running = 1; th->trace_running = 1;
raised = rb_threadptr_reset_raised(th); raised = rb_threadptr_reset_raised(th);
outer_state = th->state; outer_state = th->state;
@ -377,6 +382,7 @@ rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg)
rb_threadptr_set_raised(th); rb_threadptr_set_raised(th);
} }
th->trace_running = tracing; th->trace_running = tracing;
th->vm->trace_running = vm_tracing;
if (state) { if (state) {
JUMP_TAG(state); JUMP_TAG(state);