Fix Python 3.13 mixed-mode debugger crash by computing line numbers in-process - #8582
Merged
Rich Chiodo (rchiodo) merged 2 commits intoJul 21, 2026
Conversation
…n-process On Python 3.11+, the heavy PyFrameObject's f_lineno is 0 during execution, so the call-stack line-number computation fell back to a per-frame func-eval in the debuggee (PyFrame_GetLineNumber via CppExpressionEvaluator) on every stop. In GUI apps that pump messages this func-eval caused reentrancy/deadlock and crashed Visual Studio; it also perturbed the step engine. Replace the func-eval with an in-process decode of the code object's line table (a managed port of CPython's PyCode_Addr2Line / _PyInterpreterFrame_GetLine), computing the bytecode offset from the interpreter frame's instruction pointer (instr_ptr on 3.13+, prev_instr on 3.11/3.12) minus co_code_adaptive, then walking co_linetable. The old func-eval remains only as a last-resort fallback. This only feeds CallStackFilter (display), never step decisions, so stepping behavior is unaffected. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
🔒 Automated review in progress — Heejae Chang (@heejaechang) is auto-reviewing this PR. |
Contributor
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Heejae Chang (heejaechang)
approved these changes
Jul 21, 2026
Heejae Chang (heejaechang)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
- Handle the 3.11/3.12 entry-frame case where prev_instr points one code unit before the first instruction (negative offset). CPython's PyCode_Addr2Line returns co_firstlineno there; previously we returned 0 and fell back to the func-eval this change exists to avoid. - Extract the location-table (PEP 626) decoder into a testable internal static class PyLineTable and add table-driven DebuggerTests coverage using co_linetable bytes recorded from real 3.11.9, 3.12.7 and 3.13.14 runtimes, including NONE (no-line) markers, negative offsets, and past-end offsets. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bill Schnurr (bschnurr)
approved these changes
Jul 21, 2026
|
Heejae Chang (heejaechang)
approved these changes
Jul 21, 2026
Heejae Chang (heejaechang)
left a comment
There was a problem hiding this comment.
Approved via Review Center.
Contributor
Author
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
Rich Chiodo (rchiodo)
enabled auto-merge (squash)
July 21, 2026 23:14
Stella Huang (StellaHuang95)
approved these changes
Jul 21, 2026
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.



Problem
Mixed-mode (Python/Native) debugging crashes Visual Studio when debugging a C++ app that embeds CPython 3.11+ (reported against 3.13). When a breakpoint is hit in a GUI app that pumps messages, VS becomes unresponsive and then crashes. A console build of the same app doesn't crash but stepping from Python into native code misbehaves. Python 3.9 worked previously.
Root cause
When building the call stack,
PyFrameObject.ComputeLineNumberneeds the current line for each Python frame. On 3.11+ the frame'sf_linenois0during execution (the line is computed lazily), so the code fell back to a per-frame func-eval in the debuggee on every stop:Executing debuggee code (a func-eval) while constructing the call stack is unsafe in a GUI process: the func-eval runs the interpreter, which pumps messages / re-enters, causing reentrancy and deadlock that hangs and crashes VS. It also perturbs the step engine, which explains the broken Python→native stepping in the console case. On 3.9 the line number was read directly from the frame, so no func-eval happened and it worked.
Fix
Compute the line number in-process using memory reads only, mirroring CPython's
PyCode_Addr2Line/_PyInterpreterFrame_GetLine:PyInterpreterFrameproxy (instr_ptron 3.13+,prev_instron 3.11/3.12).instr_ptr - co_code_adaptiveand walkco_linetable(a managed port of CPython's location-table decoder) to get the line.PyFrameObject.ComputeLineNumbernow returnsf_linenowhen it's already set, otherwise decodes the line table in-process, and only falls back to the old func-eval as a last resort.This path only feeds
CallStackFilter(display), never step decisions, so stepping behavior is unaffected — but it removes the debuggee func-eval that caused the crash.Files
Python/Product/Debugger.Concord/Proxies/Structs/PyInterpreterFrame.cs— addprev_instr/instr_ptrfields andComputeLineNumber()(Addr2Line decoder).Python/Product/Debugger.Concord/Proxies/Structs/PyCodeObject311.cs— addco_linetable.Python/Product/Debugger.Concord/Proxies/Structs/PyFrameObject.cs— preferf_lineno, then in-process decode, then legacy func-eval fallback.Python/Product/Debugger.Concord/Proxies/Structs/PyFrameObject311.cs— override to decode from the interpreter frame.Testing
Manually verified against a C++ GUI app embedding CPython 3.13 (the
Examples/PythonNativesample) in VS 18 (2026 preview): breakpoints in both Python and native code are hit, stepping between Python and native works, and Visual Studio no longer hangs or crashes.Notes