Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor: Import upstream safety check into the profiler custom rb_profile_frames #2583

Merged
merged 1 commit into from
Jan 25, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ext/ddtrace_profiling_native_extension/private_vm_api_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
// for iseqs created from calls to `eval` and `instance_eval`. This makes it so that `rb_profile_frame_path` on
// the `VALUE` returned by rb_profile_frames returns `(eval)` instead of the path of the file where the `eval`
// was called from.
// * Imported fix from https://github.com/ruby/ruby/pull/7116 to avoid sampling threads that are still being created
//
// **IMPORTANT: WHEN CHANGING THIS FUNCTION, CONSIDER IF THE SAME CHANGE ALSO NEEDS TO BE MADE TO THE VARIANT FOR
// RUBY 2.2 AND BELOW WHICH IS ALSO PRESENT ON THIS FILE**
Expand Down Expand Up @@ -436,6 +437,10 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
const rb_callable_method_entry_t *cme;

// This should not happen for ddtrace (it can only happen when a thread is still being created), but I've imported
// it from https://github.com/ruby/ruby/pull/7116 in a "just in case" kind of mindset.
if (cfp == NULL) return 0;

// Avoid sampling dead threads
if (th->status == THREAD_KILLED) return 0;

Expand Down Expand Up @@ -747,6 +752,7 @@ calc_lineno(const rb_iseq_t *iseq, const VALUE *pc)
// `vm_backtrace.c` (`backtrace_each`, `backtrace_size`, `rb_ec_partial_backtrace_object`) but are conspicuously
// absent from `rb_profile_frames`. Oversight?
// * Check thread status and do not sample if thread has been killed.
// * Imported fix from https://github.com/ruby/ruby/pull/7116 to avoid sampling threads that are still being created
//
// The `rb_profile_frames` function changed quite a bit between Ruby 2.2 and 2.3. Since the change was quite complex
// I opted not to try to extend support to Ruby 2.2 using the same custom function, and instead I started
Expand All @@ -760,6 +766,10 @@ int ddtrace_rb_profile_frames(VALUE thread, int start, int limit, VALUE *buff, i
rb_thread_t *th = thread_struct_from_object(thread);
rb_control_frame_t *cfp = th->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(th);

// This should not happen for ddtrace (it can only happen when a thread is still being created), but I've imported
// it from https://github.com/ruby/ruby/pull/7116 in a "just in case" kind of mindset.
if (cfp == NULL) return 0;

// Avoid sampling dead threads
if (th->status == THREAD_KILLED) return 0;

Expand Down