summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ext/-test-/debug/profile_frames.c40
-rw-r--r--test/-ext-/debug/test_profile_frames.rb54
3 files changed, 99 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 8dd1843..0a2d0a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Oct 7 16:33:10 2013 Koichi Sasada <ko1@atdot.net>
+
+ * ext/-test-/debug/profile_frames.c:
+ test/-ext-/debug/test_profile_frames.rb: add a test for new C-APIs.
+
Mon Oct 7 16:12:36 2013 Koichi Sasada <ko1@atdot.net>
* include/ruby/debug.h: add backtrace collecting APIs for profiler.
diff --git a/ext/-test-/debug/profile_frames.c b/ext/-test-/debug/profile_frames.c
new file mode 100644
index 0000000..cbabe1b
--- /dev/null
+++ b/ext/-test-/debug/profile_frames.c
@@ -0,0 +1,40 @@
+#include "ruby/ruby.h"
+#include "ruby/debug.h"
+
+#define MAX_BUF_SIZE 0x100
+
+static VALUE
+profile_frames(VALUE self, VALUE start_v, VALUE num_v)
+{
+ int i, collected_size;
+ int start = NUM2INT(start_v);
+ int buff_size = NUM2INT(num_v);
+ VALUE buff[MAX_BUF_SIZE];
+ int lines[MAX_BUF_SIZE];
+ VALUE result = rb_ary_new();
+
+ if (buff_size > MAX_BUF_SIZE) rb_raise(rb_eRuntimeError, "too long buff_size");
+
+ collected_size = rb_profile_frames(start, buff_size, buff, lines);
+
+ for (i=0; i<collected_size; i++) {
+ VALUE ary = rb_ary_new();
+ rb_ary_push(ary, rb_profile_frame_path(buff[i]));
+ rb_ary_push(ary, rb_profile_frame_absolute_path(buff[i]));
+ rb_ary_push(ary, rb_profile_frame_label(buff[i]));
+ rb_ary_push(ary, rb_profile_frame_base_label(buff[i]));
+ 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(result, ary);
+ }
+
+ return result;
+}
+
+void
+Init_profile_frames(VALUE klass)
+{
+ rb_define_module_function(klass, "profile_frames", profile_frames, 2);
+}
diff --git a/test/-ext-/debug/test_profile_frames.rb b/test/-ext-/debug/test_profile_frames.rb
new file mode 100644
index 0000000..05e4706
--- /dev/null
+++ b/test/-ext-/debug/test_profile_frames.rb
@@ -0,0 +1,54 @@
+require 'test/unit'
+require '-test-/debug'
+
+class C
+ def self.bar(block)
+ block.call
+ end
+
+ def foo(block)
+ self.class.bar(block)
+ end
+end
+
+class TestProfileFrames < Test::Unit::TestCase
+ def test_profile_frames
+ frames = Fiber.new{
+ Fiber.yield C.new.foo(lambda{ Bug::Debug.profile_frames(0, 10) })
+ }.resume
+
+ assert_equal(4, frames.size)
+
+ labels = [
+ "block (2 levels) in test_profile_frames",
+ "bar",
+ "foo",
+ "block in test_profile_frames",
+ ]
+ base_labels = [
+ "test_profile_frames",
+ "bar",
+ "foo",
+ "test_profile_frames",
+ ]
+ classes = [
+ TestProfileFrames,
+ C, # singleton method
+ C,
+ TestProfileFrames,
+ ]
+ singleton_method_p = [
+ false, true, false, false, false,
+ ]
+
+ frames.each.with_index{|(path, absolute_path, label, base_label, first_lineno, classpath, singleton_p), 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)
+ }
+ end
+end