Skip to content

Commit e2389db

Browse files
committed
Fix thread_profile_frames crashing due to uninitialized PC
ZJIT leaves cfp->pc uninitialized in many instances, and the conditions in thread_profile_frames() was outdated, leading sampling profilers to crash. Check `cfp->pc` for validity in a way that works for both YJIT and ZJIT.
1 parent 5b5b5b3 commit e2389db

1 file changed

Lines changed: 3 additions & 6 deletions

File tree

vm_backtrace.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,7 +1729,6 @@ thread_profile_frames(rb_execution_context_t *ec, int start, int limit, VALUE *b
17291729
{
17301730
int i;
17311731
const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec);
1732-
const rb_control_frame_t *top = cfp;
17331732
const rb_callable_method_entry_t *cme;
17341733

17351734
// If this function is called inside a thread after thread creation, but
@@ -1761,11 +1760,9 @@ thread_profile_frames(rb_execution_context_t *ec, int start, int limit, VALUE *b
17611760
}
17621761

17631762
if (lines) {
1764-
// The topmost frame may not have an updated PC because the JIT
1765-
// may not have set one. The JIT compiler will update the PC
1766-
// before entering a new function (so that `caller` will work),
1767-
// so only the topmost frame could possibly have an out of date PC
1768-
if (cfp == top && cfp->jit_return) {
1763+
VALUE *iseq_encoded = ISEQ_BODY(cfp->iseq)->iseq_encoded;
1764+
// The JIT may not set the PC, so a range check is necessary
1765+
if (cfp->pc < iseq_encoded || cfp->pc > iseq_encoded) {
17691766
lines[i] = 0;
17701767
}
17711768
else {

0 commit comments

Comments
 (0)