From 3fdcfef172ae3d2d73da0f3717deea7887164da6 Mon Sep 17 00:00:00 2001 From: st0012 Date: Thu, 21 Jul 2022 22:30:27 +0100 Subject: [PATCH] Avoid setting @tc in thread_begin event This event will be triggered before the new thread even has a ThreadClient. So in this case, the @tc will be overridden to just nil, which is wrong. However, we also don't want to just set @tc to the new thread's newly created ThreadClient. This is because a thread's creation can happen during a subsession, and promptly switching @tc to another thread's ThreadClient will misfire thread suspension. --- lib/debug/session.rb | 14 ++++++++++---- test/console/thread_test.rb | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/console/thread_test.rb diff --git a/lib/debug/session.rb b/lib/debug/session.rb index db287356c..303f3336d 100644 --- a/lib/debug/session.rb +++ b/lib/debug/session.rb @@ -213,18 +213,24 @@ def request_tc(req) def process_event evt # variable `@internal_info` is only used for test - @tc, output, ev, @internal_info, *ev_args = evt + tc, output, ev, @internal_info, *ev_args = evt output.each{|str| @ui.puts str} if ev != :suspend - case ev - - when :thread_begin # special event, tc is nil + # special event, tc is nil + # and we don't want to set @tc to the newly created thread's ThreadClient + if ev == :thread_begin th = ev_args.shift q = ev_args.shift on_thread_begin th q << true + return + end + + @tc = tc + + case ev when :init enter_subsession wait_command_loop diff --git a/test/console/thread_test.rb b/test/console/thread_test.rb new file mode 100644 index 000000000..7ebb4bd31 --- /dev/null +++ b/test/console/thread_test.rb @@ -0,0 +1,24 @@ +require_relative '../support/console_test_case' + +module DEBUGGER__ + class ThreadControlTest < ConsoleTestCase + def program + <<~RUBY + 1| def foo + 2| Thread.new { sleep 5 } + 3| end + 4| + 5| 5.times do + 6| foo + 7| binding.b(do: "1 == 2") # eval Ruby code in debugger + 8| end + RUBY + end + + def test_debugger_isnt_hung_by_new_threads + debug_code(program) do + type "c" + end + end + end +end