зеркало из https://github.com/github/ruby.git
* 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:
Родитель
93184600c8
Коммит
f21d7d9831
|
@ -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 */
|
||||
|
|
14
vm_trace.c
14
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче