diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb index 00c96b3b9f..aa04cf0961 100644 --- a/test/ruby/test_backtrace.rb +++ b/test/ruby/test_backtrace.rb @@ -138,6 +138,18 @@ class TestBacktrace < Test::Unit::TestCase rec[m] end + def test_caller_with_limit + x = nil + c = Class.new do + define_method(:bar) do + x = caller(1, 1) + end + end + [c.new].group_by(&:bar) + assert_equal 1, x.length + assert_equal caller(0), caller(0, nil) + end + def test_caller_with_nil_length assert_equal caller(0), caller(0, nil) end diff --git a/version.h b/version.h index bd7e54522b..92c504153f 100644 --- a/version.h +++ b/version.h @@ -12,7 +12,7 @@ # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 46 +#define RUBY_PATCHLEVEL 47 #define RUBY_RELEASE_YEAR 2021 #define RUBY_RELEASE_MONTH 3 diff --git a/vm_backtrace.c b/vm_backtrace.c index f2cc21294c..fae65b5c2a 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -515,7 +515,7 @@ backtrace_each(const rb_execution_context_t *ec, const rb_control_frame_t *last_cfp = ec->cfp; const rb_control_frame_t *start_cfp = RUBY_VM_END_CONTROL_FRAME(ec); const rb_control_frame_t *cfp; - ptrdiff_t size, i, last, start = 0; + ptrdiff_t size, real_size, i, j, last, start = 0; int ret = 0; // In the case the thread vm_stack or cfp is not initialized, there is no backtrace. @@ -539,10 +539,10 @@ backtrace_each(const rb_execution_context_t *ec, RUBY_VM_NEXT_CONTROL_FRAME(start_cfp)); /* skip top frames */ if (start_cfp < last_cfp) { - size = last = 0; + real_size = size = last = 0; } else { - size = start_cfp - last_cfp + 1; + real_size = size = start_cfp - last_cfp + 1; if (from_last > size) { size = last = 0; @@ -568,7 +568,7 @@ backtrace_each(const rb_execution_context_t *ec, init(arg, size); /* SDR(); */ - for (i=0, cfp = start_cfp; ivm_stack + ec->vm_stack_size) - cfp); */ if (cfp->iseq) { - if (cfp->pc) { - iter_iseq(arg, cfp); - } + if (cfp->pc) { + iter_iseq(arg, cfp); + } else { + i--; + } } else if (RUBYVM_CFUNC_FRAME_P(cfp)) { const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);