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:
parent
93184600c8
commit
f21d7d9831
3 changed files with 20 additions and 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>
|
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'
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
14
vm_trace.c
14
vm_trace.c
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue