<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/vm_backtrace.c, branch v4.0.3</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Always use assert-free APIs when profiling and crashing</title>
<updated>2025-09-25T22:30:12+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2025-09-25T22:30:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=1a52c42e61878a1fe1d411a74108607766183b10'/>
<id>1a52c42e61878a1fe1d411a74108607766183b10</id>
<content type='text'>
rb_profile_frames() is used by profilers in a way such that it can run
on any instruction in the binary, and it crashed previously in the
following situation in `RUBY_DEBUG` builds:

```
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x00000001002827f0 miniruby`vm_make_env_each(ec=0x0000000101866b00, cfp=0x000000080c91bee8) at vm.c:992:74
   989              }
   990
   991              vm_make_env_each(ec, prev_cfp);
-&gt; 992              VM_FORCE_WRITE_SPECIAL_CONST(&amp;ep[VM_ENV_DATA_INDEX_SPECVAL], VM_GUARDED_PREV_EP(prev_cfp-&gt;ep));
   993          }
   994      }
   995      else {
(lldb) call rb_profile_frames(0, 100, $2, $3)
/Users/alan/ruby/vm_core.h:1448: Assertion Failed: VM_ENV_FLAGS:FIXNUM_P(flags)
ruby 3.5.0dev (2025-09-23T20:20:04Z master 06b7a70837) +PRISM [arm64-darwin25]

-- Crash Report log information --------------------------------------------
   See Crash Report log file in one of the following locations:
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0008 p:---- s:0029 e:000028 CFUNC  :lambda
/Users/alan/ruby/vm_core.h:1448: Assertion Failed: VM_ENV_FLAGS:FIXNUM_P(flags)
ruby 3.5.0dev (2025-09-23T20:20:04Z master 06b7a70837) +PRISM [arm64-darwin25]

-- Crash Report log information --------------------------------------------
&lt;snip&gt;
```

There is a small window where the control frame is invalid and fails the
assert.

The double crash also shows that in `RUBY_DEBUG` builds, the crash reporter was
previously not resilient to corrupt frame state. In release builds, it
prints more info.

Add unchecked APIs for the crash reporter and profilers so they work
as well in `RUBY_DEBUG` builds as non-debug builds.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
rb_profile_frames() is used by profilers in a way such that it can run
on any instruction in the binary, and it crashed previously in the
following situation in `RUBY_DEBUG` builds:

```
* thread #1, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x00000001002827f0 miniruby`vm_make_env_each(ec=0x0000000101866b00, cfp=0x000000080c91bee8) at vm.c:992:74
   989              }
   990
   991              vm_make_env_each(ec, prev_cfp);
-&gt; 992              VM_FORCE_WRITE_SPECIAL_CONST(&amp;ep[VM_ENV_DATA_INDEX_SPECVAL], VM_GUARDED_PREV_EP(prev_cfp-&gt;ep));
   993          }
   994      }
   995      else {
(lldb) call rb_profile_frames(0, 100, $2, $3)
/Users/alan/ruby/vm_core.h:1448: Assertion Failed: VM_ENV_FLAGS:FIXNUM_P(flags)
ruby 3.5.0dev (2025-09-23T20:20:04Z master 06b7a70837) +PRISM [arm64-darwin25]

-- Crash Report log information --------------------------------------------
   See Crash Report log file in one of the following locations:
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0008 p:---- s:0029 e:000028 CFUNC  :lambda
/Users/alan/ruby/vm_core.h:1448: Assertion Failed: VM_ENV_FLAGS:FIXNUM_P(flags)
ruby 3.5.0dev (2025-09-23T20:20:04Z master 06b7a70837) +PRISM [arm64-darwin25]

-- Crash Report log information --------------------------------------------
&lt;snip&gt;
```

There is a small window where the control frame is invalid and fails the
assert.

The double crash also shows that in `RUBY_DEBUG` builds, the crash reporter was
previously not resilient to corrupt frame state. In release builds, it
prints more info.

Add unchecked APIs for the crash reporter and profilers so they work
as well in `RUBY_DEBUG` builds as non-debug builds.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix thread_profile_frames crashing due to uninitialized PC</title>
<updated>2025-09-23T20:20:04+00:00</updated>
<author>
<name>Alan Wu</name>
<email>XrXr@users.noreply.github.com</email>
</author>
<published>2025-09-23T20:20:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=06b7a70837d831b8628ae2adde9318371c111d82'/>
<id>06b7a70837d831b8628ae2adde9318371c111d82</id>
<content type='text'>
ZJIT never sets `cfp-&gt;jit_return`, so to avoid crashing while
profiling, we need to explicitly validate the PC of the top most frame.
Particularly pertinent for profilers that call rb_profile_frames() from
within a signal handler such as Vernier and Stackprof since they
can sample at any time and observe an invalid PC.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ZJIT never sets `cfp-&gt;jit_return`, so to avoid crashing while
profiling, we need to explicitly validate the PC of the top most frame.
Particularly pertinent for profilers that call rb_profile_frames() from
within a signal handler such as Vernier and Stackprof since they
can sample at any time and observe an invalid PC.</pre>
</div>
</content>
</entry>
<entry>
<title>Fix out-of-bounds read in rb_location_ary_to_backtrace</title>
<updated>2025-09-11T12:14:25+00:00</updated>
<author>
<name>Peter Zhu</name>
<email>peter@peterzhu.ca</email>
</author>
<published>2025-09-10T23:53:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=b62753246eba4940f82a81736fc09b6517fa3965'/>
<id>b62753246eba4940f82a81736fc09b6517fa3965</id>
<content type='text'>
rb_location_ary_to_backtrace was not checking the length of the array before
reading the first element. It can be reproduced by the following script:

    begin
      raise
    rescue
      $@ = []
    end

With assertions enabled, it crashes with:

    internal/array.h:143: Assertion Failed: RARRAY_AREF:i &lt; RARRAY_LEN(ary)
    ruby 3.5.0dev (2025-09-10T19:01:16Z array-aref-assert-.. c431de0c64) +PRISM [arm64-darwin24]

    -- Crash Report log information --------------------------------------------
      See Crash Report log file in one of the following locations:
        * ~/Library/Logs/DiagnosticReports
        * /Library/Logs/DiagnosticReports
      for more details.
    Don't forget to include the above Crash Report log file in bug reports.

    -- Control frame information -----------------------------------------------
    c:0004 p:---- s:0015 e:000014 CFUNC  :set_backtrace
    c:0003 p:0013 s:0012 e:000009 RESCUE test.rb:4
    c:0002 p:0004 s:0006 e:000005 EVAL   test.rb:1 [FINISH]
    c:0001 p:0000 s:0003 E:001bb0 DUMMY  [FINISH]

    -- Ruby level backtrace information ----------------------------------------
    test.rb:1:in '&lt;main&gt;'
    test.rb:4:in 'rescue in &lt;main&gt;'
    test.rb:4:in 'set_backtrace'

    -- Threading information ---------------------------------------------------
    Total ractor count: 1
    Ruby thread count for this ractor: 1

    -- C level backtrace information -------------------------------------------
    miniruby(rb_vm_bugreport+0xb88) [0x1002adb88] vm_dump.c:1175
    miniruby(rb_vm_bugreport) (null):0
    miniruby(rb_assert_failure_detail+0xd4) [0x1003fbf90] error.c:1215
    miniruby(rb_assert_failure_detail+0x0) [0x1003fbebc] error.c:1191
    miniruby(rb_assert_failure) (null):0
    miniruby(RARRAY_AREF+0x20) [0x1003f82c8] internal/array.h:143
    miniruby(rb_keyword_error_new.cold.2) class.c:2867
    miniruby(rb_keyword_error_new.cold.4) (null):0
    miniruby(rb_location_ary_to_backtrace+0x244) [0x1002a8a60] internal/array.h:143
    miniruby(RB_TEST+0x0) [0x1000ba648] error.c:2111
    miniruby(exc_set_backtrace) error.c:2112
    miniruby(vm_call0_body+0x7d0) [0x1002a414c] vm_eval.c:164
    miniruby(rb_vm_call0+0x100) [0x100286ee4] vm_eval.c:101
    miniruby(set_backtrace+0xfc) [0x1000c88a4] eval_error.c:75
    miniruby(rb_gvar_set_entry+0x10) [0x100269230] variable.c:990
    miniruby(rb_gvar_set) variable.c:1021
    miniruby(vm_exec_core+0x1258) [0x10027a744] insns.def:319
    miniruby(rb_vm_exec+0x324) [0x100277a8c] vm.c:2666
    miniruby(rb_ec_exec_node+0x74) [0x1000c4a38] eval.c:282
    miniruby(ruby_run_node+0x64) [0x1000c4968] eval.c:320
    miniruby(rb_main+0x1c) [0x100000980] main.c:42
    miniruby(main) main.c:62
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
rb_location_ary_to_backtrace was not checking the length of the array before
reading the first element. It can be reproduced by the following script:

    begin
      raise
    rescue
      $@ = []
    end

With assertions enabled, it crashes with:

    internal/array.h:143: Assertion Failed: RARRAY_AREF:i &lt; RARRAY_LEN(ary)
    ruby 3.5.0dev (2025-09-10T19:01:16Z array-aref-assert-.. c431de0c64) +PRISM [arm64-darwin24]

    -- Crash Report log information --------------------------------------------
      See Crash Report log file in one of the following locations:
        * ~/Library/Logs/DiagnosticReports
        * /Library/Logs/DiagnosticReports
      for more details.
    Don't forget to include the above Crash Report log file in bug reports.

    -- Control frame information -----------------------------------------------
    c:0004 p:---- s:0015 e:000014 CFUNC  :set_backtrace
    c:0003 p:0013 s:0012 e:000009 RESCUE test.rb:4
    c:0002 p:0004 s:0006 e:000005 EVAL   test.rb:1 [FINISH]
    c:0001 p:0000 s:0003 E:001bb0 DUMMY  [FINISH]

    -- Ruby level backtrace information ----------------------------------------
    test.rb:1:in '&lt;main&gt;'
    test.rb:4:in 'rescue in &lt;main&gt;'
    test.rb:4:in 'set_backtrace'

    -- Threading information ---------------------------------------------------
    Total ractor count: 1
    Ruby thread count for this ractor: 1

    -- C level backtrace information -------------------------------------------
    miniruby(rb_vm_bugreport+0xb88) [0x1002adb88] vm_dump.c:1175
    miniruby(rb_vm_bugreport) (null):0
    miniruby(rb_assert_failure_detail+0xd4) [0x1003fbf90] error.c:1215
    miniruby(rb_assert_failure_detail+0x0) [0x1003fbebc] error.c:1191
    miniruby(rb_assert_failure) (null):0
    miniruby(RARRAY_AREF+0x20) [0x1003f82c8] internal/array.h:143
    miniruby(rb_keyword_error_new.cold.2) class.c:2867
    miniruby(rb_keyword_error_new.cold.4) (null):0
    miniruby(rb_location_ary_to_backtrace+0x244) [0x1002a8a60] internal/array.h:143
    miniruby(RB_TEST+0x0) [0x1000ba648] error.c:2111
    miniruby(exc_set_backtrace) error.c:2112
    miniruby(vm_call0_body+0x7d0) [0x1002a414c] vm_eval.c:164
    miniruby(rb_vm_call0+0x100) [0x100286ee4] vm_eval.c:101
    miniruby(set_backtrace+0xfc) [0x1000c88a4] eval_error.c:75
    miniruby(rb_gvar_set_entry+0x10) [0x100269230] variable.c:990
    miniruby(rb_gvar_set) variable.c:1021
    miniruby(vm_exec_core+0x1258) [0x10027a744] insns.def:319
    miniruby(rb_vm_exec+0x324) [0x100277a8c] vm.c:2666
    miniruby(rb_ec_exec_node+0x74) [0x1000c4a38] eval.c:282
    miniruby(ruby_run_node+0x64) [0x1000c4968] eval.c:320
    miniruby(rb_main+0x1c) [0x100000980] main.c:42
    miniruby(main) main.c:62
</pre>
</div>
</content>
</entry>
<entry>
<title>Allow to get a NODE_SCOPE node of dummy stack frame of ArgumentError</title>
<updated>2025-08-28T03:44:29+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-08-26T10:05:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ed8fe53e80e16f9bff592333a3082981f39216e1'/>
<id>ed8fe53e80e16f9bff592333a3082981f39216e1</id>
<content type='text'>
Previously, it was not possible to obtain a node of the callee's
`Thread::Backtrace::Location` for cases like "wrong number of
arguments" by using `RubyVM::AST.of`. This change allows that retrieval.

This is preparation for [Feature #21543].
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, it was not possible to obtain a node of the callee's
`Thread::Backtrace::Location` for cases like "wrong number of
arguments" by using `RubyVM::AST.of`. This change allows that retrieval.

This is preparation for [Feature #21543].
</pre>
</div>
</content>
</entry>
<entry>
<title>vm_backtrace.c: add RB_GC_GUARD for `name` in location_format</title>
<updated>2025-06-30T07:00:04+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-06-30T06:00:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=fd59ac6410d0cc93a8baaa42df77491abdb2e9b6'/>
<id>fd59ac6410d0cc93a8baaa42df77491abdb2e9b6</id>
<content type='text'>
`name` is used via `RSTRING_PTR` within rb_str_catf, which may allocate
and thus potentially trigger GC. Although `name` is still referenced
by a local variable, the compiler might optimize away the reference
before the GC sees it, especially under aggressive optimization or when
debugging tools like ASAN are used.

This patch adds an explicit `RB_GC_GUARD` to ensure `name` is kept alive
until after the last use.

While it's not certain this is the root cause of the following observed
use-after-poison ASAN error, I believe this fix is indeed needed and
hopefully a likely candidate for preventing the error.

```
==1960369==ERROR: AddressSanitizer: use-after-poison on address 0x7ec6a00f1d88 at pc 0x5fb5bcafcf2e bp 0x7ffcc1178cb0 sp 0x7ffcc1178470
READ of size 61 at 0x7ec6a00f1d88 thread T0
    #0 0x5fb5bcafcf2d in __asan_memcpy (/tmp/ruby/build/trunk_asan/ruby+0x204f2d) (BuildId: 6d92c84a27b87cfd253c38eeb552593f215ffb3d)
    #1 0x5fb5bcde1fa5 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10
    #2 0x5fb5bcde1fa5 in ruby_nonempty_memcpy /tmp/ruby/src/trunk_asan/include/ruby/internal/memory.h:758:16
    #3 0x5fb5bcde1fa5 in ruby__sfvwrite /tmp/ruby/src/trunk_asan/sprintf.c:1083:9
    #4 0x5fb5bcde1521 in BSD__sprint /tmp/ruby/src/trunk_asan/vsnprintf.c:318:8
    #5 0x5fb5bcde0fbc in BSD_vfprintf /tmp/ruby/src/trunk_asan/vsnprintf.c:1215:3
    #6 0x5fb5bcdde4b1 in ruby_vsprintf0 /tmp/ruby/src/trunk_asan/sprintf.c:1164:5
    #7 0x5fb5bcddd648 in rb_str_vcatf /tmp/ruby/src/trunk_asan/sprintf.c:1234:5
    #8 0x5fb5bcddd648 in rb_str_catf /tmp/ruby/src/trunk_asan/sprintf.c:1245:11
    #9 0x5fb5bcf97c67 in location_format /tmp/ruby/src/trunk_asan/vm_backtrace.c:462:9
    #10 0x5fb5bcf97c67 in location_to_str /tmp/ruby/src/trunk_asan/vm_backtrace.c:493:12
    #11 0x5fb5bcf90a37 in location_to_str_dmyarg /tmp/ruby/src/trunk_asan/vm_backtrace.c:795:12
    #12 0x5fb5bcf90a37 in backtrace_collect /tmp/ruby/src/trunk_asan/vm_backtrace.c:786:28
    #13 0x5fb5bcf90a37 in backtrace_to_str_ary /tmp/ruby/src/trunk_asan/vm_backtrace.c:804:9
    #14 0x5fb5bcf90a37 in rb_backtrace_to_str_ary /tmp/ruby/src/trunk_asan/vm_backtrace.c:816:9
    #15 0x5fb5bd335b25 in exc_backtrace /tmp/ruby/src/trunk_asan/error.c:1904:15
    #16 0x5fb5bd335b25 in rb_get_backtrace /tmp/ruby/src/trunk_asan/error.c:1924:16
```
https://ci.rvm.jp/results/trunk_asan@ruby-sp1/5810304
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`name` is used via `RSTRING_PTR` within rb_str_catf, which may allocate
and thus potentially trigger GC. Although `name` is still referenced
by a local variable, the compiler might optimize away the reference
before the GC sees it, especially under aggressive optimization or when
debugging tools like ASAN are used.

This patch adds an explicit `RB_GC_GUARD` to ensure `name` is kept alive
until after the last use.

While it's not certain this is the root cause of the following observed
use-after-poison ASAN error, I believe this fix is indeed needed and
hopefully a likely candidate for preventing the error.

```
==1960369==ERROR: AddressSanitizer: use-after-poison on address 0x7ec6a00f1d88 at pc 0x5fb5bcafcf2e bp 0x7ffcc1178cb0 sp 0x7ffcc1178470
READ of size 61 at 0x7ec6a00f1d88 thread T0
    #0 0x5fb5bcafcf2d in __asan_memcpy (/tmp/ruby/build/trunk_asan/ruby+0x204f2d) (BuildId: 6d92c84a27b87cfd253c38eeb552593f215ffb3d)
    #1 0x5fb5bcde1fa5 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10
    #2 0x5fb5bcde1fa5 in ruby_nonempty_memcpy /tmp/ruby/src/trunk_asan/include/ruby/internal/memory.h:758:16
    #3 0x5fb5bcde1fa5 in ruby__sfvwrite /tmp/ruby/src/trunk_asan/sprintf.c:1083:9
    #4 0x5fb5bcde1521 in BSD__sprint /tmp/ruby/src/trunk_asan/vsnprintf.c:318:8
    #5 0x5fb5bcde0fbc in BSD_vfprintf /tmp/ruby/src/trunk_asan/vsnprintf.c:1215:3
    #6 0x5fb5bcdde4b1 in ruby_vsprintf0 /tmp/ruby/src/trunk_asan/sprintf.c:1164:5
    #7 0x5fb5bcddd648 in rb_str_vcatf /tmp/ruby/src/trunk_asan/sprintf.c:1234:5
    #8 0x5fb5bcddd648 in rb_str_catf /tmp/ruby/src/trunk_asan/sprintf.c:1245:11
    #9 0x5fb5bcf97c67 in location_format /tmp/ruby/src/trunk_asan/vm_backtrace.c:462:9
    #10 0x5fb5bcf97c67 in location_to_str /tmp/ruby/src/trunk_asan/vm_backtrace.c:493:12
    #11 0x5fb5bcf90a37 in location_to_str_dmyarg /tmp/ruby/src/trunk_asan/vm_backtrace.c:795:12
    #12 0x5fb5bcf90a37 in backtrace_collect /tmp/ruby/src/trunk_asan/vm_backtrace.c:786:28
    #13 0x5fb5bcf90a37 in backtrace_to_str_ary /tmp/ruby/src/trunk_asan/vm_backtrace.c:804:9
    #14 0x5fb5bcf90a37 in rb_backtrace_to_str_ary /tmp/ruby/src/trunk_asan/vm_backtrace.c:816:9
    #15 0x5fb5bd335b25 in exc_backtrace /tmp/ruby/src/trunk_asan/error.c:1904:15
    #16 0x5fb5bd335b25 in rb_get_backtrace /tmp/ruby/src/trunk_asan/error.c:1924:16
```
https://ci.rvm.jp/results/trunk_asan@ruby-sp1/5810304
</pre>
</div>
</content>
</entry>
<entry>
<title>Change how to correct the first lineno in the backtrace on ArgumentError</title>
<updated>2025-06-24T02:39:58+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-06-23T13:00:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a18fa86351f6b904f9d49ff4a23f15aae7680821'/>
<id>a18fa86351f6b904f9d49ff4a23f15aae7680821</id>
<content type='text'>
Follow up to fix 3b7373fd00a0ba456498a7b7d6de2a47c96434a2.
In that commit, the line number in the first frame was overwritten after
the whole backtrace was created. There was a problem that the line
number was overwritten even if the location was backpatched.

Instead, this commit uses first_lineno if the frame is
VM_FRAME_MAGIC_DUMMY when generating the backtrace.

Before the patch:
```
$ ./miniruby -e '[1, 2].inject(:tap)'
-e:in '&lt;main&gt;': wrong number of arguments (given 1, expected 0) (ArgumentError)
        from -e:1:in 'Enumerable#inject'
        from -e:1:in '&lt;main&gt;'
```

After the patch:
```
$ ./miniruby -e '[1, 2].inject(:tap)'
-e:1:in '&lt;main&gt;': wrong number of arguments (given 1, expected 0) (ArgumentError)
        from -e:1:in 'Enumerable#inject'
        from -e:1:in '&lt;main&gt;'
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Follow up to fix 3b7373fd00a0ba456498a7b7d6de2a47c96434a2.
In that commit, the line number in the first frame was overwritten after
the whole backtrace was created. There was a problem that the line
number was overwritten even if the location was backpatched.

Instead, this commit uses first_lineno if the frame is
VM_FRAME_MAGIC_DUMMY when generating the backtrace.

Before the patch:
```
$ ./miniruby -e '[1, 2].inject(:tap)'
-e:in '&lt;main&gt;': wrong number of arguments (given 1, expected 0) (ArgumentError)
        from -e:1:in 'Enumerable#inject'
        from -e:1:in '&lt;main&gt;'
```

After the patch:
```
$ ./miniruby -e '[1, 2].inject(:tap)'
-e:1:in '&lt;main&gt;': wrong number of arguments (given 1, expected 0) (ArgumentError)
        from -e:1:in 'Enumerable#inject'
        from -e:1:in '&lt;main&gt;'
```
</pre>
</div>
</content>
</entry>
<entry>
<title>Exclude internal frames from backtrace</title>
<updated>2025-06-18T05:51:56+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-05-02T08:12:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=10767283dd0277a1d780790ce6bde67cf2c832a2'/>
<id>10767283dd0277a1d780790ce6bde67cf2c832a2</id>
<content type='text'>
This changeset suppresses backtrace locations like
`&lt;internal:array&gt;:211` as much as possible.

Before the patch:
```
$ ruby -e '[1].fetch_values(42)'
&lt;internal:array&gt;:211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (IndexError)
        from &lt;internal:array&gt;:211:in 'block in Array#fetch_values'
        from &lt;internal:array&gt;:211:in 'Array#map!'
        from &lt;internal:array&gt;:211:in 'Array#fetch_values'
        from -e:1:in '&lt;main&gt;'
```

After the patch:
```
$ ./miniruby -e '[1].fetch_values(42)'
-e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError)
        from -e:1:in '&lt;main&gt;'
```

Specifically:

* The special backtrace handling of BUILTIN_ATTR_C_TRACE is now always
  applied to frames with `&lt;internal:...&gt;`.
* When multiple consecutive internal frames appear, all but the bottom
  (caller-side) frame are removed.

[Misc #20968]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This changeset suppresses backtrace locations like
`&lt;internal:array&gt;:211` as much as possible.

Before the patch:
```
$ ruby -e '[1].fetch_values(42)'
&lt;internal:array&gt;:211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (IndexError)
        from &lt;internal:array&gt;:211:in 'block in Array#fetch_values'
        from &lt;internal:array&gt;:211:in 'Array#map!'
        from &lt;internal:array&gt;:211:in 'Array#fetch_values'
        from -e:1:in '&lt;main&gt;'
```

After the patch:
```
$ ./miniruby -e '[1].fetch_values(42)'
-e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError)
        from -e:1:in '&lt;main&gt;'
```

Specifically:

* The special backtrace handling of BUILTIN_ATTR_C_TRACE is now always
  applied to frames with `&lt;internal:...&gt;`.
* When multiple consecutive internal frames appear, all but the bottom
  (caller-side) frame are removed.

[Misc #20968]
</pre>
</div>
</content>
</entry>
<entry>
<title>refactor: rename bt_update_cfunc_loc to bt_backpatch_loc</title>
<updated>2025-06-18T05:51:56+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-05-02T07:06:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ca10c521ff748bded89e481ab3f1767a8e56a71c'/>
<id>ca10c521ff748bded89e481ab3f1767a8e56a71c</id>
<content type='text'>
In preparation for using it to update not only cfunc frames but also
internal frames, the function (and related variable names) are chagned.

I felt that the word "backpatch" is more appropriate than the more
general verb "update" here.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
In preparation for using it to update not only cfunc frames but also
internal frames, the function (and related variable names) are chagned.

I felt that the word "backpatch" is more appropriate than the more
general verb "update" here.
</pre>
</div>
</content>
</entry>
<entry>
<title>Make `rb_debug_inspector_backtrace_locations` return a raw backtrace</title>
<updated>2025-06-04T10:53:16+00:00</updated>
<author>
<name>Yusuke Endoh</name>
<email>mame@ruby-lang.org</email>
</author>
<published>2025-06-04T07:44:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=caa6ba1a46afa1bc696adc5fe91ee992f9570c89'/>
<id>caa6ba1a46afa1bc696adc5fe91ee992f9570c89</id>
<content type='text'>
Previously, a user of the debug inspector API was supposed to use
`rb_debug_inspector_backtrace_locations` to get an array of
`Thread::Backtrace::Location`, and then used its index to get more
information from `rb_debug_inspector _frame_binding_get(index)`, etc.

However, `rb_debug_inspector_backtrace_locations` returned an array of
backtraces excluding rescue/ensure frames. On the other hand,
`rb_debug_inspector_frame_binding_get(index)` interprets index with
rescue/ensure frames. This led to inconsistency of the index, and it was
very difficult to correctly use the debug inspector API.

This is a minimal fix for the issue by making
`rb_debug_inspector_backtrace_locations` return a raw backtrace
including rescue/ensure frames.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, a user of the debug inspector API was supposed to use
`rb_debug_inspector_backtrace_locations` to get an array of
`Thread::Backtrace::Location`, and then used its index to get more
information from `rb_debug_inspector _frame_binding_get(index)`, etc.

However, `rb_debug_inspector_backtrace_locations` returned an array of
backtraces excluding rescue/ensure frames. On the other hand,
`rb_debug_inspector_frame_binding_get(index)` interprets index with
rescue/ensure frames. This led to inconsistency of the index, and it was
very difficult to correctly use the debug inspector API.

This is a minimal fix for the issue by making
`rb_debug_inspector_backtrace_locations` return a raw backtrace
including rescue/ensure frames.
</pre>
</div>
</content>
</entry>
<entry>
<title>[Bug #21127] Thread deadlock does not display backtraces (#12721)</title>
<updated>2025-02-14T07:31:58+00:00</updated>
<author>
<name>Masataka Pocke Kuwabara</name>
<email>kuwabara@pocke.me</email>
</author>
<published>2025-02-14T07:31:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=0cab608d3a7791c229eea2ebe276494f063c8176'/>
<id>0cab608d3a7791c229eea2ebe276494f063c8176</id>
<content type='text'>
Previously, Ruby displayed backtraces for each thread on deadlock. However, it has not been shown since Ruby 3.0.
It should display the backtrace for debugging.

Co-authored-by: Jeremy Evans &lt;code@jeremyevans.net&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, Ruby displayed backtraces for each thread on deadlock. However, it has not been shown since Ruby 3.0.
It should display the backtrace for debugging.

Co-authored-by: Jeremy Evans &lt;code@jeremyevans.net&gt;
</pre>
</div>
</content>
</entry>
</feed>
