From: Roger Pack Date: 2009-06-10T03:39:06+09:00 Subject: [ruby-core:23777] Re: [Bug #977] caller for all threads patch On Mon, Jun 8, 2009 at 5:06 PM, 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) I really like it. Appears that it wants default to be level 0 [?] Also should it go in intern.h? Here is my hack at those two updates. This will be very nice. Thanks! -=r Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 23658) +++ include/ruby/intern.h (working copy) @@ -317,6 +317,7 @@ void rb_gc_mark_threads(void); void rb_thread_schedule(void); void rb_thread_wait_fd(int); +VALUE rb_thread_backtrace(VALUE thval, int lev); int rb_thread_fd_writable(int); void rb_thread_fd_close(int); int rb_thread_alone(void); Index: vm_eval.c =================================================================== --- vm_eval.c (revision 23658) +++ vm_eval.c (working copy) @@ -1342,6 +1342,19 @@ } 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 (revision 23658) +++ thread.c (working copy) @@ -3817,6 +3817,26 @@ 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 = 0; + 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 @@ 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);