Skip to content

Commit

Permalink
* vm_backtrace.c, include/ruby/debug.h: add new APIs
Browse files Browse the repository at this point in the history
* VALUE rb_profile_frame_method_name(VALUE frame)
* VALUE rb_profile_frame_qualified_method_name(VALUE frame)
* iseq.c (rb_iseq_klass), internal.h: add new internal function
  rb_iseq_method_name().
* ext/-test-/debug/profile_frames.c (profile_frames),
  test/-ext-/debug/test_profile_frames.rb: add a test.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
ko1 committed Oct 8, 2013
1 parent 377758f commit cff2b2b
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 5 deletions.
12 changes: 12 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
Tue Oct 8 21:03:35 2013 Koichi Sasada <ko1@atdot.net>

* vm_backtrace.c, include/ruby/debug.h: add new APIs
* VALUE rb_profile_frame_method_name(VALUE frame)
* VALUE rb_profile_frame_qualified_method_name(VALUE frame)

* iseq.c (rb_iseq_klass), internal.h: add new internal function
rb_iseq_method_name().

* ext/-test-/debug/profile_frames.c (profile_frames),
test/-ext-/debug/test_profile_frames.rb: add a test.

Tue Oct 8 16:11:11 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>

* array.c (rb_ary_uniq): use rb_hash_values(), as well as the case no
Expand Down
2 changes: 2 additions & 0 deletions ext/-test-/debug/profile_frames.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ profile_frames(VALUE self, VALUE start_v, VALUE num_v)
rb_ary_push(ary, rb_profile_frame_first_lineno(buff[i]));
rb_ary_push(ary, rb_profile_frame_classpath(buff[i]));
rb_ary_push(ary, rb_profile_frame_singleton_method_p(buff[i]));
rb_ary_push(ary, rb_profile_frame_method_name(buff[i]));
rb_ary_push(ary, rb_profile_frame_qualified_method_name(buff[i]));

rb_ary_push(result, ary);
}
Expand Down
2 changes: 2 additions & 0 deletions include/ruby/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ VALUE rb_profile_frame_base_label(VALUE frame);
VALUE rb_profile_frame_first_lineno(VALUE frame);
VALUE rb_profile_frame_classpath(VALUE frame);
VALUE rb_profile_frame_singleton_method_p(VALUE frame);
VALUE rb_profile_frame_method_name(VALUE frame);
VALUE rb_profile_frame_qualified_method_name(VALUE frame);

/* debug inspector APIs */
typedef struct rb_debug_inspector_struct rb_debug_inspector_t;
Expand Down
1 change: 1 addition & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ VALUE rb_iseq_label(VALUE iseqval);
VALUE rb_iseq_base_label(VALUE iseqval);
VALUE rb_iseq_first_lineno(VALUE iseqval);
VALUE rb_iseq_klass(VALUE iseqval); /* completely temporary fucntion */
VALUE rb_iseq_method_name(VALUE self);

/* load.c */
VALUE rb_get_load_path(void);
Expand Down
14 changes: 14 additions & 0 deletions iseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,20 @@ rb_iseq_klass(VALUE self)
return iseq->local_iseq->klass;
}

VALUE
rb_iseq_method_name(VALUE self)
{
rb_iseq_t *iseq, *local_iseq;
GetISeqPtr(self, iseq);
local_iseq = iseq->local_iseq;
if (local_iseq->type == ISEQ_TYPE_METHOD) {
return local_iseq->location.base_label;
}
else {
return Qnil;
}
}

static
VALUE iseq_data_to_ary(rb_iseq_t *iseq);

Expand Down
36 changes: 31 additions & 5 deletions test/-ext-/debug/test_profile_frames.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
require '-test-/debug'

class SampleClassForTestProfileFrames
class Sample2
def baz(block)
block.call
end
end

def self.bar(block)
block.call
Sample2.new.baz(block)
end

def foo(block)
Expand All @@ -17,38 +23,58 @@ def test_profile_frames
Fiber.yield SampleClassForTestProfileFrames.new.foo(lambda{ Bug::Debug.profile_frames(0, 10) })
}.resume

assert_equal(4, frames.size)

labels = [
"block (2 levels) in test_profile_frames",
"baz",
"bar",
"foo",
"block in test_profile_frames",
]
base_labels = [
"test_profile_frames",
"baz",
"bar",
"foo",
"test_profile_frames",
]
classes = [
TestProfileFrames,
SampleClassForTestProfileFrames::Sample2,
SampleClassForTestProfileFrames, # singleton method
SampleClassForTestProfileFrames,
TestProfileFrames,
]
singleton_method_p = [
false, true, false, false, false,
false, false, true, false, false, false,
]
methdo_names = [
"test_profile_frames",
"baz",
"bar",
"foo",
"test_profile_frames",
]
qualified_method_names = [
"TestProfileFrames#test_profile_frames",
"SampleClassForTestProfileFrames::Sample2#baz",
"SampleClassForTestProfileFrames.bar",
"SampleClassForTestProfileFrames#foo",
"TestProfileFrames#test_profile_frames",
]

assert_equal(labels.size, frames.size)

frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno, classpath, singleton_p), i|
frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno,
classpath, singleton_p, method_name, qualified_method_name), i|
err_msg = "#{i}th frame"
assert_equal(__FILE__, path, err_msg)
assert_equal(__FILE__, absolute_path, err_msg)
assert_equal(labels[i], label, err_msg)
assert_equal(base_labels[i], base_label, err_msg)
assert_equal(classes[i].to_s, classpath, err_msg)
assert_equal(singleton_method_p[i], singleton_p, err_msg)
assert_equal(methdo_names[i], method_name, err_msg)
assert_equal(qualified_method_names[i], qualified_method_name, err_msg)
}
end
end
27 changes: 27 additions & 0 deletions vm_backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1287,3 +1287,30 @@ rb_profile_frame_singleton_method_p(VALUE frame)
return Qfalse;
}
}

VALUE
rb_profile_frame_method_name(VALUE frame)
{
return rb_iseq_method_name(frame2iseq(frame));
}

VALUE
rb_profile_frame_qualified_method_name(VALUE frame)
{
VALUE method_name = rb_iseq_method_name(frame2iseq(frame));
if (method_name != Qnil) {
VALUE classpath = rb_profile_frame_classpath(frame);
VALUE singleton_p = rb_profile_frame_singleton_method_p(frame);

if (classpath != Qnil) {
return rb_sprintf("%"PRIsVALUE"%s%"PRIsVALUE,
classpath, singleton_p == Qtrue ? "." : "#", method_name);
}
else {
return method_name;
}
}
else {
return Qnil;
}
}

0 comments on commit cff2b2b

Please sign in to comment.