summaryrefslogtreecommitdiff
path: root/vm_backtrace.c
diff options
context:
space:
mode:
authorDaisuke Aritomo <osyoyu@osyoyu.com>2023-09-29 15:35:36 +0900
committerKoichi Sasada <ko1@atdot.net>2023-10-31 11:16:18 +0900
commit4adf418be963b3554962b2f27057be81486c57d9 (patch)
treed43c3006925aaacdf522b58b752b860f6b94875a /vm_backtrace.c
parent02ecc3c8550af1aab7916975e7019b2a3ffe8591 (diff)
[Feature #10602] Add new API rb_profile_thread_frames()
Add a new API rb_profile_thread_frames(), which is essentialy a per-thread version of rb_profile_frames(). While the original rb_profile_frames() always returns results about the current active thread obtained by GET_EC(), this new API takes a Thread to be profiled as an argument. This should come in handy when profiling I/O-bound programs such as webapps, since this new API allows us to learn about Threads performing I/O (which do not have the GVL). Profiling worker threads (such as Sidekiq workers) may be another application. Implements [Feature #10602] Co-authored-by: Mike Perham <mike@perham.net>
Diffstat (limited to 'vm_backtrace.c')
-rw-r--r--vm_backtrace.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/vm_backtrace.c b/vm_backtrace.c
index 34ebde0f0b..2414adae6e 100644
--- a/vm_backtrace.c
+++ b/vm_backtrace.c
@@ -1584,11 +1584,10 @@ rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc)
return dc->backtrace;
}
-int
-rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
+static int
+thread_profile_frames(rb_execution_context_t *ec, int start, int limit, VALUE *buff, int *lines)
{
int i;
- const rb_execution_context_t *ec = GET_EC();
const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
const rb_control_frame_t *top = cfp;
const rb_callable_method_entry_t *cme;
@@ -1650,6 +1649,20 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
return i;
}
+int
+rb_profile_frames(int start, int limit, VALUE *buff, int *lines)
+{
+ rb_execution_context_t *ec = GET_EC();
+ return thread_profile_frames(ec, start, limit, buff, lines);
+}
+
+int
+rb_profile_thread_frames(VALUE thread, int start, int limit, VALUE *buff, int *lines)
+{
+ rb_thread_t *th = rb_thread_ptr(thread);
+ return thread_profile_frames(th->ec, start, limit, buff, lines);
+}
+
static const rb_iseq_t *
frame2iseq(VALUE frame)
{