summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--test/ruby/test_thread.rb10
-rw-r--r--thread.c9
-rw-r--r--vm_eval.c19
4 files changed, 44 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index a822ad0ebe..064fbe0e62 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Jun 14 14:57:57 2009 Koichi Sasada <ko1@atdot.net>
+
+ * thread.c, vm_eval.c: add Thread.backtrace.
+
+ * test/ruby/test_thread.rb: add a test.
+
Sun Jun 14 13:58:32 2009 Koichi Sasada <ko1@atdot.net>
* transcode.c (transcode_restartable0): revert last commit because
diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb
index b460cadea9..d0c35d8273 100644
--- a/test/ruby/test_thread.rb
+++ b/test/ruby/test_thread.rb
@@ -516,4 +516,14 @@ class TestThreadGroup < Test::Unit::TestCase
c.class_eval { def initialize; end }
assert_raise(ThreadError) { c.new.start }
end
+
+ def test_backtrace
+ Thread.new{
+ assert_equal(Array, Thread.main.backtrace.class)
+ }.join
+
+ t = Thread.new{}
+ t.join
+ assert_equal(nil, t.backtrace)
+ end
end
diff --git a/thread.c b/thread.c
index 573ace640c..efe5d02dd5 100644
--- a/thread.c
+++ b/thread.c
@@ -3817,6 +3817,14 @@ ruby_suppress_tracing(VALUE (*func)(VALUE, int), VALUE arg, int always)
return result;
}
+VALUE rb_thread_backtrace(VALUE thval);
+
+static VALUE
+rb_thread_backtrace_m(VALUE thval)
+{
+ return rb_thread_backtrace(thval);
+}
+
/*
* +Thread+ encapsulates the behavior of a thread of
* execution, including the main thread of the Ruby script.
@@ -3873,6 +3881,7 @@ Init_Thread(void)
rb_define_method(rb_cThread, "abort_on_exception=", rb_thread_abort_exc_set, 1);
rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0);
rb_define_method(rb_cThread, "group", rb_thread_group, 0);
+ rb_define_method(rb_cThread, "backtrace", rb_thread_backtrace_m, 0);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
diff --git a/vm_eval.c b/vm_eval.c
index 596701e2c0..2dff373e42 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1348,6 +1348,25 @@ rb_make_backtrace(void)
}
VALUE
+rb_thread_backtrace(VALUE thval)
+{
+ rb_thread_t *th;
+ GetThreadPtr(thval, th);
+
+ switch (th->status) {
+ case THREAD_RUNNABLE:
+ case THREAD_STOPPED:
+ case THREAD_STOPPED_FOREVER:
+ break;
+ case THREAD_TO_KILL:
+ case THREAD_KILLED:
+ return Qnil;
+ }
+
+ return vm_backtrace(th, 0);
+}
+
+VALUE
rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg)
{
return vm_backtrace_each(GET_THREAD(), -1, iter, arg);