From d797d318390f5ebbf6d97e2f2fee93db3f072a8b Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Wed, 4 Jun 2025 16:52:50 +0900 Subject: [PATCH] The debug gem can abort when stepping into a rescue clause: ``` $ ruby -Ilib exe/rdbg rescue-test.rb [1, 7] in rescue-test.rb => 1| 1.times do 2| begin 3| raise 4| rescue 5| p 1 6| end 7| end =>#0
at rescue-test.rb:1 (rdbg) s # step command [1, 7] in rescue-test.rb 1| 1.times do 2| begin => 3| raise 4| rescue 5| p 1 6| end 7| end =>#0 block in
at rescue-test.rb:3 #1 Integer#times at :257 # and 1 frames (use `bt' command for all frames) (rdbg) s # step command /home/mame/work/debug/lib/debug/thread_client.rb:85:in 'DEBUGGER__::ThreadClient#default_frame_formatter': undefined method '+' for nil (NoMethodError) "#{colorize_blue("block")}#{args_str} in #{colorize_blue(block_loc + level)}" ^ from /home/mame/work/debug/lib/debug/thread_client.rb:755:in 'Method#call' from /home/mame/work/debug/lib/debug/thread_client.rb:755:in 'DEBUGGER__::ThreadClient#frame_str' from /home/mame/work/debug/lib/debug/thread_client.rb:742:in 'block in DEBUGGER__::ThreadClient#show_frames' from :257:in 'Integer#times' from /home/mame/work/debug/lib/debug/thread_client.rb:739:in 'DEBUGGER__::ThreadClient#show_frames' from /home/mame/work/debug/lib/debug/thread_client.rb:304:in 'DEBUGGER__::ThreadClient#suspend' from /home/mame/work/debug/lib/debug/thread_client.rb:358:in 'block in DEBUGGER__::ThreadClient#step_tp' from rescue-test.rb:5:in 'block in
' from :257:in 'Integer#times' from rescue-test.rb:1:in '
' rescue-test.rb:3:in 'block in
': unhandled exception from :257:in 'Integer#times' from rescue-test.rb:1:in '
' ``` This is because `rb_debug_inspector_backtrace_locations` returned a modified backtrace, which skips rescue/ensure frames, but `rb_debug_inspector_frame_XXX_get`'s index is considered for a raw backtrace, which includes rescue/ensure frames. The problem wil be fixed by https://github.com/ruby/ruby/pull/13510. However, now the backtrace includes rescue/ensure frames, so some tests in debug gem fails. This fixes the test failures. --- test/console/frame_block_identifier_test.rb | 4 +-- test/console/nested_break_test.rb | 2 +- test/console/rescue_test.rb | 28 +++++++++++++++++++++ test/console/trap_test.rb | 1 - 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 test/console/rescue_test.rb diff --git a/test/console/frame_block_identifier_test.rb b/test/console/frame_block_identifier_test.rb index a4349da19..dd483a583 100644 --- a/test/console/frame_block_identifier_test.rb +++ b/test/console/frame_block_identifier_test.rb @@ -46,8 +46,8 @@ def test_frame_block_identifier / 15\| end/, / 16\| end/, /=>\#0\tWhatever\#some_method at .*/, - / \#1\tblock in Kernel\#loop at :168/, - / \# and 2 frames \(use `bt' command for all frames\)/, + / \#1\t.*/, + / \# and (?:2|3) frames \(use `bt' command for all frames\)/, //, /Stop by \#0 BP \- Line .*/ ]) diff --git a/test/console/nested_break_test.rb b/test/console/nested_break_test.rb index d7e2437e5..c152b3f01 100644 --- a/test/console/nested_break_test.rb +++ b/test/console/nested_break_test.rb @@ -83,7 +83,7 @@ def test_multiple_nested_break assert_line_num 2 type 'p foo(142)' type 'bt' - assert_line_text(/\#7\s+
/) # TODO: can be changed + assert_line_text(/\#\d+\s+
/) type 'c' assert_line_text(/143/) diff --git a/test/console/rescue_test.rb b/test/console/rescue_test.rb new file mode 100644 index 000000000..f0225147b --- /dev/null +++ b/test/console/rescue_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require_relative '../support/console_test_case' + +module DEBUGGER__ + class RescueTest < ConsoleTestCase + def program + <<~RUBY + 1| 1.times do + 2| begin + 3| raise + 4| rescue + 5| p :ok + 6| end + 7| end + RUBY + end + + def test_rescue + debug_code program, remote: false do + type 's' + type 's' + type 'c' + end + end + end if RUBY_VERSION.to_f >= 3.5 +end + diff --git a/test/console/trap_test.rb b/test/console/trap_test.rb index 17c4ccfa7..0f18e14ac 100644 --- a/test/console/trap_test.rb +++ b/test/console/trap_test.rb @@ -16,7 +16,6 @@ def test_sigint debug_code program, remote: false do type 'b 3' type 'c' - assert_line_num 2 assert_line_text(/is registered as SIGINT handler/) type 'sigint' assert_line_num 3