@@ -390,12 +390,16 @@ def _by_type(self, *msgs):
390390 ret [msg .__class__ ] = msg
391391 return ret
392392
393- def write_continue (self , wait_for_response = True , thread_id = "*" ):
394- continue_request = self .write_request (pydevd_schema .ContinueRequest (pydevd_schema .ContinueArguments (threadId = thread_id )))
393+ def write_continue (self , wait_for_response = True , thread_id = "*" , single_thread = False ):
394+ arguments = pydevd_schema .ContinueArguments (threadId = thread_id )
395+ if single_thread :
396+ arguments .singleThread = True
397+ continue_request = self .write_request (pydevd_schema .ContinueRequest (arguments ))
395398
396399 if wait_for_response :
397- if thread_id != "*" :
398- # event, response may be sent in any order
400+ if single_thread :
401+ # When singleThread=True, only the specified thread resumes.
402+ # ContinuedEvent and ContinueResponse may arrive in any order.
399403 msg1 = self .wait_for_json_message ((ContinuedEvent , ContinueResponse ))
400404 msg2 = self .wait_for_json_message ((ContinuedEvent , ContinueResponse ))
401405 by_type = self ._by_type (msg1 , msg2 )
@@ -406,8 +410,10 @@ def write_continue(self, wait_for_response=True, thread_id="*"):
406410 assert continued_ev .body .allThreadsContinued == False
407411 assert continue_response .body .allThreadsContinued == False
408412 else :
409- # The continued event is received before the response.
410- self .wait_for_continued_event (all_threads_continued = True )
413+ # Default: all threads resume regardless of the threadId sent.
414+ # Per the DAP spec, singleThread must be explicitly True to
415+ # resume only one thread. Wait for the continue response with
416+ # allThreadsContinued=True.
411417 continue_response = self .wait_for_response (continue_request )
412418 assert continue_response .body .allThreadsContinued
413419
@@ -800,6 +806,9 @@ def test_case_json_suspend_notification(case_setup_dap):
800806 json_facade .write_make_initial_run ()
801807
802808 json_hit = json_facade .wait_for_thread_stopped (line = break1_line )
809+ # Per the DAP spec, a ContinueRequest without singleThread=True must resume
810+ # all threads even when a specific threadId is provided. Verify the response
811+ # has allThreadsContinued=True (the correct behavior).
803812 json_facade .write_continue (thread_id = json_hit .thread_id )
804813
805814 json_hit = json_facade .wait_for_thread_stopped (line = break1_line )
@@ -808,6 +817,33 @@ def test_case_json_suspend_notification(case_setup_dap):
808817 writer .finished_ok = True
809818
810819
820+ def test_case_json_continue_all_threads (case_setup_dap ):
821+ """Regression test: ContinueRequest with a specific threadId (no singleThread=True)
822+ must resume ALL threads, not just the requested one. This tests the fix for the
823+ in-process debug adapter scenario where the adapter does not transform threadId to '*'.
824+ """
825+ with case_setup_dap .test_file ("_debugger_case_multi_threads_continue.py" ) as writer :
826+ json_facade = JsonFacade (writer )
827+ # Simulate the in-process adapter: disable single notification mode.
828+ # In this mode the server receives a specific threadId (not '*') directly
829+ # from the client without the adapter transforming it.
830+ json_facade .writer .write_multi_threads_single_notification (False )
831+ break_line = writer .get_line_index_with_content ("Break here" )
832+ json_facade .write_launch ()
833+ json_facade .write_set_breakpoints (break_line )
834+ json_facade .write_make_initial_run ()
835+
836+ # Wait for the breakpoint to be hit.
837+ json_hit = json_facade .wait_for_thread_stopped (line = break_line )
838+
839+ # Send ContinueRequest with the specific thread's id (no singleThread=True).
840+ # Per the DAP spec this must resume ALL threads, not just the specified one.
841+ # The response must have allThreadsContinued=True.
842+ json_facade .write_continue (thread_id = json_hit .thread_id )
843+
844+ writer .finished_ok = True
845+
846+
811847def test_case_handled_exception_no_break_on_generator (case_setup_dap ):
812848 with case_setup_dap .test_file ("_debugger_case_ignore_exceptions.py" ) as writer :
813849 json_facade = JsonFacade (writer )
0 commit comments