From a3a2d461aa8cbcc1cb4a7c859acfaa4cbd686e77 Mon Sep 17 00:00:00 2001 From: Alexander Momchilov Date: Wed, 13 May 2026 17:13:53 -0400 Subject: [PATCH] [Bug #22070] Fix segfault in `Thread.each_caller_location` --- test/ruby/test_backtrace.rb | 10 ++++++++++ vm_backtrace.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb index dad7dfcb55..332d76c58e 100644 --- a/test/ruby/test_backtrace.rb +++ b/test/ruby/test_backtrace.rb @@ -191,6 +191,16 @@ class TestBacktrace < Test::Unit::TestCase assert_equal(cl.map(&:to_s), ary.map(&:to_s)) end + def test_each_caller_location_single_cfunc_frame + assert_normal_exit <<~'RUBY' + tap { Thread.each_caller_location(1, 1) { |loc| loc.label } } + RUBY + + cl = nil; ary = [] + tap { cl = caller_locations(1, 1); Thread.each_caller_location(1, 1) { |x| ary << x } } + assert_equal(cl.map(&:to_s), ary.map(&:to_s)) + end + def test_caller_locations_first_label def self.label caller_locations.first.label diff --git a/vm_backtrace.c b/vm_backtrace.c index ea876b1502..85a0658612 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -751,7 +751,7 @@ rb_ec_partial_backtrace_object(const rb_execution_context_t *ec, long start_fram bt_backpatch_loc(backpatch_counter, loc, CFP_ISEQ(cfp), CFP_PC(cfp)); RB_OBJ_WRITTEN(btobj, Qundef, CFP_ISEQ(cfp)); if (do_yield) { - bt_yield_loc(loc - backpatch_counter, backpatch_counter, btobj); + bt_yield_loc(loc - backpatch_counter + 1, backpatch_counter, btobj); } break; }