mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm_trace.c: rename and add TracePoint APIs.
(1) TracePoint.new(...){...} creates a new trace point but does not make it enable. (2) TracePoint.trace(...){...} creats a new trace point and enable it (same as old behavior). (3) TracePoint#enable make it enable (renamed from TracePoint#retrace). If block given, when enable only in block. (4) TracePoint#disable make it disable (renamed from TracePoint#untrace). If block given, when disable only in block. (5) TracePoint#enabled? returns this trace is enable or not. * test/ruby/test_settracefunc.rb: addd tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
553931962a
commit
1da641a16b
3 changed files with 138 additions and 38 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Tue Nov 20 19:02:44 2012 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm_trace.c: rename and add TracePoint APIs.
|
||||
(1) TracePoint.new(...){...} creates a new trace point
|
||||
but does not make it enable.
|
||||
(2) TracePoint.trace(...){...} creats a new trace point
|
||||
and enable it (same as old behavior).
|
||||
(3) TracePoint#enable make it enable (renamed from TracePoint#retrace).
|
||||
If block given, when enable only in block.
|
||||
(4) TracePoint#disable make it disable (renamed from TracePoint#untrace).
|
||||
If block given, when disable only in block.
|
||||
(5) TracePoint#enabled? returns this trace is enable or not.
|
||||
|
||||
* test/ruby/test_settracefunc.rb: addd tests.
|
||||
|
||||
Tue Nov 20 18:35:05 2012 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm_trace.c: add two methods:
|
||||
|
|
|
@ -437,7 +437,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
18: xyzzy = XYZZY.new
|
||||
19: xyzzy.foo
|
||||
20: begin; raise RuntimeError; rescue RuntimeError => raised_exc; end
|
||||
21: trace.untrace
|
||||
21: trace.disable
|
||||
EOF
|
||||
self.class.class_eval{remove_const(:XYZZY)}
|
||||
|
||||
|
@ -493,7 +493,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
[:c_call, 20, "xyzzy", Module, :===, RuntimeError,:outer, :nothing],
|
||||
[:c_return,20, "xyzzy", Module, :===, RuntimeError,:outer, true],
|
||||
[:line, 21, "xyzzy", TestSetTraceFunc, method, self, :outer, :nothing],
|
||||
[:c_call, 21, "xyzzy", TracePoint, :untrace, trace, :outer, :nothing],
|
||||
[:c_call, 21, "xyzzy", TracePoint, :disable, trace, :outer, :nothing],
|
||||
]
|
||||
|
||||
return events, answer_events
|
||||
|
@ -533,6 +533,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
|
||||
def test_tracepoint
|
||||
events1, answer_events = *trace_by_tracepoint()
|
||||
|
||||
mesg = events1.map{|e|
|
||||
"#{e[0]} - #{e[2]}:#{e[1]} id: #{e[4]}"
|
||||
}.join("\n")
|
||||
|
@ -567,7 +568,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
tap{}
|
||||
tap{}
|
||||
tap{}
|
||||
trace.untrace
|
||||
trace.disable
|
||||
|
||||
# passed tp is unique, `trace' object which is genereted by TracePoint.trace
|
||||
tps.each{|tp|
|
||||
|
@ -581,7 +582,7 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
tp_store = tp
|
||||
}
|
||||
tap{}
|
||||
trace.untrace
|
||||
trace.disable
|
||||
|
||||
assert_raise(RuntimeError){tp_store.line}
|
||||
assert_raise(RuntimeError){tp_store.event}
|
||||
|
@ -593,4 +594,49 @@ class TestSetTraceFunc < Test::Unit::TestCase
|
|||
assert_raise(RuntimeError){tp_store.return_value}
|
||||
assert_raise(RuntimeError){tp_store.raised_exception}
|
||||
end
|
||||
|
||||
def foo
|
||||
end
|
||||
|
||||
def test_tracepoint_enable
|
||||
ary = []
|
||||
trace = TracePoint.new(:call){|tp|
|
||||
ary << tp.id
|
||||
}
|
||||
foo
|
||||
trace.enable{
|
||||
foo
|
||||
}
|
||||
foo
|
||||
assert_equal([:foo], ary)
|
||||
end
|
||||
|
||||
def test_tracepoint_disable
|
||||
ary = []
|
||||
trace = TracePoint.trace(:call){|tp|
|
||||
ary << tp.id
|
||||
}
|
||||
foo
|
||||
trace.disable{
|
||||
foo
|
||||
}
|
||||
foo
|
||||
trace.disable
|
||||
assert_equal([:foo, :foo], ary)
|
||||
end
|
||||
|
||||
def test_tracepoint_enabled
|
||||
trace = TracePoint.trace(:call){|tp|
|
||||
#
|
||||
}
|
||||
assert_equal(true, trace.enabled?)
|
||||
trace.disable{
|
||||
assert_equal(false, trace.enabled?)
|
||||
trace.enable{
|
||||
assert_equal(true, trace.enabled?)
|
||||
}
|
||||
}
|
||||
trace.disable
|
||||
assert_equal(false, trace.enabled?)
|
||||
end
|
||||
end
|
||||
|
|
107
vm_trace.c
107
vm_trace.c
|
@ -818,66 +818,95 @@ tp_call_trace(VALUE tpval, rb_trace_arg_t *trace_arg)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
tp_set_trace(VALUE tpval)
|
||||
tp_enable(VALUE tpval)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
|
||||
if (tp->target_th) {
|
||||
rb_thread_add_event_hook2(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG);
|
||||
}
|
||||
else {
|
||||
rb_add_event_hook2((rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG);
|
||||
}
|
||||
tp->tracing = 1;
|
||||
return Qundef;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_disable(VALUE tpval)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
|
||||
if (tp->target_th) {
|
||||
rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval);
|
||||
}
|
||||
else {
|
||||
rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval);
|
||||
}
|
||||
tp->tracing = 0;
|
||||
return Qundef;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static VALUE
|
||||
tp_enable_m(VALUE tpval)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
|
||||
if (tp->tracing) {
|
||||
/* already tracing */
|
||||
/* TODO: raise error? */
|
||||
}
|
||||
else {
|
||||
if (tp->target_th) {
|
||||
rb_thread_add_event_hook2(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG);
|
||||
}
|
||||
else {
|
||||
rb_add_event_hook2((rb_event_hook_func_t)tp_call_trace, tp->events, tpval, RUBY_HOOK_FLAG_SAFE | RUBY_HOOK_FLAG_RAW_ARG);
|
||||
}
|
||||
tp->tracing = 1;
|
||||
rb_raise(rb_eRuntimeError, "trace is already enable");
|
||||
}
|
||||
|
||||
return tpval;
|
||||
tp_enable(tpval);
|
||||
if (rb_block_given_p()) {
|
||||
return rb_ensure(rb_yield, tpval, tp_disable, tpval);
|
||||
}
|
||||
else {
|
||||
return tpval;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_unset_trace(VALUE tpval)
|
||||
tp_disable_m(VALUE tpval)
|
||||
{
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
|
||||
if (!tp->tracing) {
|
||||
/* not tracing */
|
||||
/* TODO: raise error? */
|
||||
}
|
||||
else {
|
||||
if (tp->target_th) {
|
||||
rb_thread_remove_event_hook_with_data(tp->target_th->self, (rb_event_hook_func_t)tp_call_trace, tpval);
|
||||
}
|
||||
else {
|
||||
rb_remove_event_hook_with_data((rb_event_hook_func_t)tp_call_trace, tpval);
|
||||
}
|
||||
tp->tracing = 0;
|
||||
rb_raise(rb_eRuntimeError, "trace is not enable");
|
||||
}
|
||||
|
||||
return tpval;
|
||||
tp_disable(tpval);
|
||||
if (rb_block_given_p()) {
|
||||
return rb_ensure(rb_yield, tpval, tp_enable, tpval);
|
||||
}
|
||||
else {
|
||||
return tpval;
|
||||
}
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_initialize(rb_thread_t *target_th, rb_event_flag_t events, VALUE proc)
|
||||
tp_enabled_p(VALUE tpval)
|
||||
{
|
||||
VALUE tpval = tp_alloc(rb_cTracePoint);
|
||||
rb_tp_t *tp = tpptr(tpval);
|
||||
return tp->tracing ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_initialize(VALUE klass, rb_thread_t *target_th, rb_event_flag_t events, VALUE proc)
|
||||
{
|
||||
VALUE tpval = tp_alloc(klass);
|
||||
rb_tp_t *tp;
|
||||
TypedData_Get_Struct(tpval, rb_tp_t, &tp_data_type, tp);
|
||||
|
||||
tp->proc = proc;
|
||||
tp->events = events;
|
||||
|
||||
tp_set_trace(tpval);
|
||||
|
||||
return tpval;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_trace_s(int argc, VALUE *argv)
|
||||
tp_new_s(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
rb_event_flag_t events = 0;
|
||||
int i;
|
||||
|
@ -895,7 +924,15 @@ tp_trace_s(int argc, VALUE *argv)
|
|||
rb_raise(rb_eThreadError, "must be called with a block");
|
||||
}
|
||||
|
||||
return tp_initialize(0, events, rb_block_proc());
|
||||
return tp_initialize(self, 0, events, rb_block_proc());
|
||||
}
|
||||
|
||||
static VALUE
|
||||
tp_trace_s(int argc, VALUE *argv, VALUE self)
|
||||
{
|
||||
VALUE trace = tp_new_s(argc, argv, self);
|
||||
tp_enable(trace);
|
||||
return trace;
|
||||
}
|
||||
|
||||
/* This function is called from inits.c */
|
||||
|
@ -911,10 +948,12 @@ Init_vm_trace(void)
|
|||
rb_cTracePoint = rb_define_class("TracePoint", rb_cObject);
|
||||
rb_undef_alloc_func(rb_cTracePoint);
|
||||
rb_undef_method(CLASS_OF(rb_cTracePoint), "new");
|
||||
rb_define_singleton_method(rb_cTracePoint, "new", tp_new_s, -1);
|
||||
rb_define_singleton_method(rb_cTracePoint, "trace", tp_trace_s, -1);
|
||||
|
||||
rb_define_method(rb_cTracePoint, "retrace", tp_set_trace, 0);
|
||||
rb_define_method(rb_cTracePoint, "untrace", tp_unset_trace, 0);
|
||||
rb_define_method(rb_cTracePoint, "enable", tp_enable_m, 0);
|
||||
rb_define_method(rb_cTracePoint, "disable", tp_disable_m, 0);
|
||||
rb_define_method(rb_cTracePoint, "enabled?", tp_enabled_p, 0);
|
||||
|
||||
rb_define_method(rb_cTracePoint, "event", tp_attr_event_m, 0);
|
||||
rb_define_method(rb_cTracePoint, "line", tp_attr_line_m, 0);
|
||||
|
|
Loading…
Reference in a new issue