Repository navigation
[release/11.0] Size the RESOLVE_UPDATE_METADATA events in DbgTransportSession::GetEventSize - #135597
Open
github-actions[bot] wants to merge 1 commit into
Open
github-actions[bot] wants to merge 1 commit into
github-actions[bot] wants to merge 1 commit into
Conversation
…entSize (#134717) **Problem:** on Linux, a debugger can crash the process it is debugging when it requests the locals of a method that a profiler has rewritten. If a profiler has given a method new locals with `SetILFunctionBody`, a debugger that requests that method's locals can make the debuggee die with SIGSEGV in `Debugger::SerializeModuleMetaData`. An IDE's Variables pane can make that request automatically, for example at an exception stop. In my VS Code sessions, the Debug Console reported the crashed debuggee as `exited with code 0`. With checked builds, an unpatched process that sends one of the affected events asserts and aborts instead; with an unpatched checked `mscordbi`, that is the debugger itself. I reproduced the crash on 8.0, 9.0, 10.0, 11.0 RC1 and `main`, and the omission is present in the source back to at least 6.0. Standard Windows builds do not use this transport. macOS does, and I did not test it. **Cause:** the Unix debugger transport sizes each event it sends with `DbgTransportSession::GetEventSize`, which has no case for the four `DB_IPCE_RESOLVE_UPDATE_METADATA_*` events. They fall to `default:`. Release builds therefore send all four with only the event header; for the three that carry a payload, the receiver reads stale bytes where the `MetadataUpdateRequest` payload should be. Checked builds assert `"Unknown debugger event type"` in the sending process. Under the default `LegacyCompatPolicy`, the debugger starts this exchange when it meets a local-signature token that is not in its cached metadata, such as a new signature that a profiler has added. **Fix:** size the three events that carry `MetadataUpdateRequest`, and add `_2_RESULT`, which carries only the header `hr`, to the existing zero-payload group. The linked issue has the details, a minimal repro, and results on 8.0 to 11.0. | event | direction | fields used | |---|---|---| | `_1` | debugger → runtime | `vmModule` | | `_1_RESULT` | runtime → debugger | `pMetadataStart`, `nMetadataSize` | | `_2` | debugger → runtime | `pMetadataStart` (the buffer to free) | | `_2_RESULT` | runtime → debugger | none | `GetEventSize` is compiled into both `mscordbi` and `coreclr` (`debug/di/shared.cpp`, `debug/ee/shared.cpp`), and each side sizes the events it sends, so both binaries need the change. ## Validation With the minimal repro from the issue (a small C profiler that adds one unused local, and a debugger requesting locals at an exception stop: netcoredbg, or VS Code where marked), 3 runs per cell unless noted: | build | before | after | |---|---|---| | 10.0.12 release, linux-x64 and linux-arm64 | debuggee SIGSEGV, 3/3 | correct locals, 3/3 | | 10.0.12 checked, linux-x64 | debugger asserts in `GetEventSize`, 3/3 | correct locals, 0 asserts, 3/3 | | 11.0 RC1 tag, release, linux-x64 (VS Code, 1 run) | debuggee SIGSEGV | correct locals | | `main` at `c29faec90e46`, linux-x64 (VS Code; release, and checked for "after"¹) | debuggee SIGSEGV, 2/2 | correct locals: release 3/3; checked 1/1, no assert | ¹ The checked `main` build also swaps the DAC, JIT and CoreLib. Within each release configuration, only `libcoreclr.so` and `libmscordbi.so` differ between the before and after builds. macOS shares the transport and was not tested. The controls (no profiler; an unchanged body; a new MemberRef without a new local) read the expected locals under netcoredbg on 8.0, 9.0 and 10.0. On 11.0 RC1, netcoredbg returns only `$exception` at the stop even with no profiler, so the 11.0 rows use VS Code. ## Tests I did not find a test in this repo that exercises the debugger transport, so this PR adds no test, as with #97476 and #110122. The repro is attached to the issue. #134715 proposes a checked-build check that every declared event type is either sized or explicitly listed as never sent. I am happy to add a test if you can point me at the right place. ## Servicing The omission is present on every supported branch. I'd suggest this for `release/11.0`, ideally before GA; per-branch patches for 10.0, 9.0 and 8.0 are attached to the issue in case you judge those worth servicing. If you do service it, the text below may save time: <details> <summary>Servicing template</summary> **Customer Impact** - [x] Customer reported (#134714) - [ ] Found internally On Linux, when a profiler has given a method new locals with `SetILFunctionBody`, a debugger that requests that method's locals (an IDE's Variables pane can do so automatically, e.g. at an exception stop) can crash the debuggee. macOS uses the same transport and was not tested; standard Windows builds do not use it. **Regression** - [ ] Yes - [x] No Present since at least 6.0 (checked from `v6.0.36`). **Testing** The minimal repro in #134714: release and checked 10.0.12 builds (linux-x64), release (linux-arm64), the 11.0 RC1 tag and `main` (linux-x64, VS Code). **Risk** Low. Cases are added to a size switch for events that were sent header-only. Only the sent length of these three events grows, to include their payload; no other event, struct or framing changes. The debugger (`libmscordbi.so`) and the runtime (`libcoreclr.so`) should ship together: a fixed `mscordbi` with an unpatched `coreclr` can send a stale pointer back in `_2` for the runtime to free (see the issue). Both are in the runtime package. </details> Resolves #134714 > [!NOTE] > This change and description were prepared with AI assistance (Anthropic Claude and OpenAI Codex), under my direction. I reviewed them before posting.
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
2 of 4 tasks
jkotas
approved these changes
Oct 11, 2026
This branch has not been deployed
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.
Backport of #134717 to release/11.0
/cc @steveisok @pcshrosbree
Customer Impact
On Linux, when a profiler has given a method new locals with
SetILFunctionBody, a debugger that requests that method's locals (an IDE's Variables pane can do so automatically, e.g. at an exception stop) can crash the debuggee. macOS uses the same transport and was not tested; standard Windows builds do not use it.Regression
Present since at least 6.0 (checked from
v6.0.36).Testing
The minimal repro in #134714: release and checked 10.0.12 builds (linux-x64), release (linux-arm64), the 11.0 RC1 tag and
main(linux-x64, VS Code).No automated test was added: the original PR did not find an existing test in this repo that exercises the debugger transport, as with #97476 and #110122. The repro is attached to #134714.
Risk
Low. Cases are added to a size switch for events that were sent header-only. Only the sent length of these three events grows, to include their payload; no other event, struct or framing changes. The debugger (
libmscordbi.so) and the runtime (libcoreclr.so) should ship together: a fixedmscordbiwith an unpatchedcoreclrcan send a stale pointer back in_2for the runtime to free (see #134714). Both are in the runtime package.IMPORTANT: If this backport is for a servicing release, please verify that:
release/X.0-staging, notrelease/X.0.release/X.0(no-stagingsuffix).Package authoring no longer needed in .NET 9
IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.