Feature #977
closedcaller for all threads patch
Description
=begin
Here is a patch which provides backtrace for all current threads, instead of just the current one.
http://ph7spot.com/articles/caller_for_all_threads
Author said it would be great to have it accepted upstream.
Thoughts?
-=r
=end
Updated by rogerdpack (Roger Pack) almost 16 years ago
=begin
oops that's a feature request not a bug--for some reason I thought it would default to a feature request since that's the view from whence I clicked "Submit issue"
My bad.
-=r
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
- Assignee set to ko1 (Koichi Sasada)
- Target version set to 1.9.2
=begin
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
I made a patch to Thread#caller(lev=1). It may be more flexible than
fetching "all" backtrace.
How about it? (not tested enough)
Index: vm_eval.c¶
--- vm_eval.c (リビジョン 23650)
+++ vm_eval.c (作業コピー)
@@ -1342,6 +1342,19 @@ rb_make_backtrace(void)
}VALUE
+rb_thread_backtrace(VALUE thval, int lev)
+{
- rb_thread_t *th;
- GetThreadPtr(thval, th);
- if (th->status != THREAD_KILLED && GET_THREAD() != th) {
- lev--;
- }
- return vm_backtrace(th, lev);
+}+VALUE
rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg)
{
return vm_backtrace_each(GET_THREAD(), -1, iter, arg);
Index: thread.c--- thread.c (リビジョン 23651)
+++ thread.c (作業コピー)
@@ -3817,6 +3817,26 @@ ruby_suppress_tracing(VALUE (*func)(VALU
return result;
}+VALUE rb_thread_backtrace(VALUE thval, int lev);
+
+static VALUE
+rb_thread_caller_m(int argc, VALUE *argv, VALUE thval)
+{
- VALUE level;
- int lev;
- rb_scan_args(argc, argv, "01", &level);
- if (NIL_P(level))
- lev = 1;
- else
- lev = NUM2INT(level);
- if (lev < 0)
- rb_raise(rb_eArgError, "negative level (%d)", lev);
- return rb_thread_backtrace(thval, lev);
+}/*
- +Thread+ encapsulates the behavior of a thread of
- execution, including the main thread of the Ruby script.
@@ -3873,6 +3893,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, "caller", rb_thread_caller_m, -1);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
Roger Pack wrote::
Bug #977: caller for all threads patch
http://redmine.ruby-lang.org/issues/show/977Author: Roger Pack
Status: Open, Priority: NormalHere is a patch which provides backtrace for all current threads, instead of just the current one.
http://ph7spot.com/articles/caller_for_all_threads
Author said it would be great to have it accepted upstream.
Thoughts?
-=r
--
// SASADA Koichi at atdot dot net
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
Hongli Lai wrote::
SASADA Koichi wrote:
I made a patch to Thread#caller(lev=1). It may be more flexible than
fetching "all" backtrace.
How about it? (not tested enough)The ability to see all running threads' backtraces, without needing a
reference to each one of those threads, is caller_for_all_thread's main
advantage. It's very useful for debugging a live application. Replacing
it with Thread#caller would require one to maintain references to all
threads that one wants to inspect. Does Ruby already provide some way to
obtain a list of all running threads?
def caller_for_all_thread
Thread.list.map{|t| t.caller}
end
--
// SASADA Koichi at atdot dot net
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
Rocky Bernstein wrote::
One thing I think might be cool is rather than raising an error for a
negative Fixnum value is to count from the other end. So caller(-1) is the
least-recent call.If you want me to try my hand at extending the below, let me know.
Check the following code.
VALUE
+rb_thread_backtrace(VALUE thval, int lev)
+{
- rb_thread_t *th;
- GetThreadPtr(thval, th);
- if (th->status != THREAD_KILLED && GET_THREAD() != th) {
lev--;
- }
- return vm_backtrace(th, lev);
+}
--
// SASADA Koichi at atdot dot net
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
Rocky Bernstein wrote::
I was suggesting that rather than raise an error here, treat this like array
indexes do and basically use size - level. (By the way, also suggests it
might be cool to add some sort of length or size function.)I guess I missed something, but what?
I had misunderstood your suggestion. At first, you should suggest the
"Kernel.caller" specification, not the Thread#caller spec.
Regards,¶
// SASADA Koichi at atdot dot net
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
Roger Pack wrote::
I really like it.
Appears that it wants default to be level 0 [?]
Thank you for your notice.
I've change my thought. Thread#backtrace() is more proffered name.
- On Thread#caller(lev), nobody may use lev (!= 0)
- Deciding the semantics of lev except zero may be difficult
How about it?
--
// SASADA Koichi at atdot dot net
=end
Updated by ko1 (Koichi Sasada) over 15 years ago
=begin
Roger Pack wrote::
Roger Pack wrote::
I really like it.
Appears that it wants default to be level 0 [?]
Thank you for your notice.I've change my thought. Thread#backtrace() is more proffered name.
- On Thread#caller(lev), nobody may use lev (!= 0)
- Deciding the semantics of lev except zero may be difficult
That sounds better. Then the semantics for caller never change. So
this would be Thread#backtrace can have lev > 0?
Either way's good for me.
No. Same as Exception#backtrace.
How about it, matz?
--
// SASADA Koichi at atdot dot net
=end
Updated by matz (Yukihiro Matsumoto) over 15 years ago
=begin
Hi,
In message "Re: [ruby-core:23812] Re: [Bug #977] caller for all threads patch"
on Fri, 12 Jun 2009 08:28:53 +0900, SASADA Koichi ko1@atdot.net writes:
|No. Same as Exception#backtrace.
|How about it, matz?
I see no problem.
matz.
=end
Updated by rogerdpack (Roger Pack) over 15 years ago
=begin
You can close this one--thank you to Ko1 for implementing it for me.
=end
Updated by shyouhei (Shyouhei Urabe) over 15 years ago
- Status changed from Open to Closed
=begin
=end