diff --git a/ChangeLog b/ChangeLog index c9f73cd467..fdaaad4161 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Fri Jun 13 17:58:58 2014 Koichi Sasada + + * vm_trace.c: add new method TracePoint.stat to debug + TracePoint mechanism. + + Ruby users should not use this method. So I don't note this method + in the NEWS file. + + * test/runner.rb: detect zombie active TracePoints with + TracePoint.stat. + Fri Jun 13 17:46:31 2014 Koichi Sasada * vm_trace.c: clear and restore recursive checking thread local data diff --git a/test/runner.rb b/test/runner.rb index 2956b85df8..e7bff26e8c 100644 --- a/test/runner.rb +++ b/test/runner.rb @@ -22,6 +22,12 @@ module Test::Unit def after_teardown super assert_empty(Process.waitall) + + # detect zombie traces. + TracePoint.stat.each{|key, (activated, deleted)| + assert_equal(0, activated, 'The number of active trace events should be zero.') + # puts "TracePoint - deleted: #{deleted}" if deleted > 0 + } end end class TestCase diff --git a/vm_trace.c b/vm_trace.c index fe10abf50f..80084019e4 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -1314,6 +1314,48 @@ tracepoint_inspect(VALUE self) } } +static void +tracepoint_stat_event_hooks(VALUE hash, VALUE key, rb_event_hook_t *hook) +{ + int active = 0, deleted = 0; + + while (hook) { + if (hook->hook_flags & RUBY_EVENT_HOOK_FLAG_DELETED) { + deleted++; + } + else { + active++; + } + hook = hook->next; + } + + rb_hash_aset(hash, key, rb_ary_new3(2, INT2FIX(active), INT2FIX(deleted))); +} + +/* + * call-seq: + * TracePoint.stat -> obj + * + * Returns internal information of TracePoint. + * + * The contents of the returned value are implementation specific. + * It may be changed in future. + * + * This method is only for debugging TracePoint itself. + */ + +static VALUE +tracepoint_stat_s(VALUE self) +{ + rb_vm_t *vm = GET_VM(); + VALUE stat = rb_hash_new(); + + tracepoint_stat_event_hooks(stat, vm->self, vm->event_hooks.hooks); + /* TODO: thread local hooks */ + + return stat; +} + static void Init_postponed_job(void); /* This function is called from inits.c */ @@ -1407,6 +1449,8 @@ Init_vm_trace(void) rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0); rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0); + rb_define_singleton_method(rb_cTracePoint, "stat", tracepoint_stat_s, 0); + /* initialized for postponed job */ Init_postponed_job();