summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-21 10:14:26 +0000
committerktsj <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-21 10:14:26 +0000
commitf21d7d98318919c730a5dbcca9f2c931ebd66898 (patch)
tree0fccea5533fff66247a7d84fa49096e2e8b058a4
parent93184600c8dfe84f03d2c41035c5bc0fdbe4e84f (diff)
* 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--ChangeLog9
-rw-r--r--vm_core.h1
-rw-r--r--vm_trace.c14
3 files changed, 20 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 4ac3c5b403..db92606bb4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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'
diff --git a/vm_core.h b/vm_core.h
index af87f8a567..5e68b8e9ab 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -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);