Repository navigation
Fix hang after rapid continue with multiple threads - #2081
Merged
Rich Chiodo (rchiodo) merged 1 commit intoOct 8, 2026
Merged
Conversation
In single notification mode the continue response waits for the next resume notification. A continue that arrives after the last stop was already reported as resumed, or one whose stop is replaced by another thread's breakpoint before any suspended thread leaves its wait loop, never got one, so the adapter blocked on it and stopped answering every later request. Keep the callbacks in AbstractSingleNotificationBehavior under its lock, call them right away when no suspend notification is waiting for a resume, and send the pending resume before a new suspend notification.
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Contributor
|
🔒 Automated review in progress — Heejae Chang (@heejaechang) is auto-reviewing this PR. |
Heejae Chang (heejaechang)
approved these changes
Oct 7, 2026
Heejae Chang (heejaechang)
left a comment
Contributor
There was a problem hiding this comment.
Approved via Review Center.
Rich Chiodo (rchiodo)
approved these changes
Oct 7, 2026
Rich Chiodo (rchiodo)
left a comment
Contributor
There was a problem hiding this comment.
Approved via Review Center.
Contributor
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Contributor
Author
|
The failures in both runs are Windows tests that also fail on main without this change (test_thread_count and test_systemexit in build 4660, test_unsupported_configure_from_environment in build 4648), and test_continue_while_running passed on every job. Let me know if you would like me to look into any of them. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #2048.
In single notification mode (the debugpy default),
on_continue_requestsends thecontinueresponse only when the next resume notification goes out. Two cases never get one: acontinuethat arrives after the last stop was already reported as resumed (the second of two quick F5 presses), and acontinuewhose stop is replaced by another thread's breakpoint before any suspended thread leaves its wait loop. The adapter waits for that response inside its message loop, so it stops answering every later request: the frozen session in the issue.The pydevd log in the issue shows the first case. Right after
continue(seq 122) is processed, the next thread to leave its wait loop logsResume not sent (it was already sent). Last resume 18 >= Last suspend 18. The resume for that stop had already gone out, so thiscontinuehad nothing left to wait for.What changed, all in
pydevd.py:ThreadsSuspendedSingleNotificationtoAbstractSingleNotificationBehaviorand use its_lock, so the check below can't race a resume.add_on_resumed_callbackcalls the callback right away when the last suspend notification was already followed by a resume notification.continued, thecontinueresponse, thenstopped.A
continuefor a stop not yet reported as resumed still waits, as the comment inon_continue_requestasks.New tests:
test_single_notification_5and_6cover the two cases, andtest_continue_while_runningsends a secondcontinuethrough the adapter while the debuggee runs.Testing on macOS 26.6.2 with
PYDEVD_USE_CYTHON=NO:test_single_notification.py: 6 passed on CPython 3.10.6 and 3.13.15, and 20 repeated runs passed on 3.10.6.tests/debugpy/test_threads.pyon 3.10.6: 9 passed.test_continue_while_runningwithDEBUGPY_TESTS_FULL=1: 14 passed.test_debugger_json.pyandtest_debugger.py(suspend notification, continue, pause, logpoints and others): all passed.test_continue_while_runninghangs on the secondcontinueuntil the 90 second timeout. The two unit tests fail withAttributeError, or with main's callback handling patched in,assert [1] == [1, 2]andassert 'suspend' == 'resume'.continuerequests per stop: all 7 hang on main and all finish with this change, on 3.10.6 and 3.13.15.ruff check .passes.The adapter still blocks its message loop on the
continueresponse; I can look at that separately.