[Release] Snap main branch for release#5786
Merged
hoyosjs merged 51 commits intorelease/stablefrom Apr 2, 2026
Merged
Conversation
test.sh|ps1 -methodfilter "Namespace.ClassName.MethodName" test.sh|ps1 -classfilter "Namespace.ClassName" --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Max Charlamb <44248479+max-charlamb@users.noreply.github.com>
…st failures (#5700) ## Improve Console Output Visibility in CollectCommand Tests This PR addresses issue #5698 by making console output visible when tests fail. ### Changes completed: - [x] Modified MockConsole to accept optional ITestOutputHelper parameter - [x] Updated MockConsole.Write methods to multiplex output to ITestOutputHelper when provided - [x] Injected ITestOutputHelper into CollectCommandFunctionalTests - [x] Injected ITestOutputHelper into CollectLinuxCommandFunctionalTests - [x] Injected ITestOutputHelper into ConsoleExporterTests - [x] Updated all test methods to pass ITestOutputHelper to MockConsole - [x] Optimized implementation to avoid unnecessary string allocations - [x] Made exception handling more specific with exception message check - [x] Added FlushTestLogging method to ensure buffered output is written - [x] Simplified comments per code review feedback - [x] Fixed case-sensitive exception filter to use OrdinalIgnoreCase comparison - [x] Refactored test logging logic into BufferTestLogging helper method - [x] Renamed FlushOutput to FlushTestLogging for clarity - [x] Verified backward compatibility with existing tests - [x] All tests pass successfully ### Key features: - **Intelligent buffering**: Accumulates text until complete lines are ready to avoid fragmenting output - **Performance optimized**: Only processes buffer when incoming text contains newlines - **Robust exception handling**: Uses case-insensitive comparison to catch InvalidOperationException properly - **Backward compatible**: Optional parameter means existing tests don't need changes - **FlushTestLogging method**: Ensures any remaining buffered output is written before assertions - **Clean separation**: Test logging logic extracted into dedicated helper methods ### Result: Console output including error messages and exceptions is now visible in test output under "Standard Output Messages:", making it much easier to diagnose issues when tests fail. <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Can you extend the CollectCommandFunctionalTests and CollectLinuxCommandFunctionalTests to increase visibility on the console output observed whenever there are failures. Currently they're swalled by MockConsole, and so we don't know what exception occurred. See #5698 for an example. There is also a suggestion to inject ITestOutputHelper, </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com> Co-authored-by: noahfalk <6243776+noahfalk@users.noreply.github.com>
- Add -all flag to DumpMT that includes class details and method descriptors - -all implies -MD but -MD remains independently usable - Create DisplayClassDetails() helper to avoid duplication between DumpMT -all and DumpClass - Simplify Canonical MethodTable display: only show when it differs from current MT - Update PrintVC and PrintObj to use same simplified logic - Keep DumpClass as separate command for backward compatibility - Update documentation for both Windows and Unix
This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260130.4](https://dev.azure.com/dnceng/internal/_build/results?buildId=2891960) ([299615](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/299615)) - **Date Produced**: January 31, 2026 3:24:21 AM UTC - **Commit**: [b0f891cf7c1febc0ebbae7dd787f8a0b4c0cbc95](dotnet/arcade@b0f891c) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26066.3 to 10.0.0-beta.26080.4][1] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [1]: dotnet/arcade@af17297...b0f891c [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
…#5684) - [x] Analyze the usage of $(RepoRootDir) in Debugger.Tests.Config.txt files - [x] Add MSBuild targets to copy AuxMsbuildFiles and debuggee sources to artifacts directory: - [x] CommonTestRunner.csproj: Copy debuggees (Tracee, EventPipeTracee, StackTracee, ExitCodeTracee) and `eng/AuxMsbuildFiles` - [x] DbgShim.UnitTests.csproj: Copy `src/tests/DbgShim.UnitTests/Debuggees` and `eng/AuxMsbuildFiles` - [x] SOS.UnitTests.csproj: Copy `src/tests/SOS.UnitTests/Debuggees`, `eng/AuxMsbuildFiles`, and `lldbplugin.tests` - [x] Update Debugger.Tests.Config.txt files to use $(ArtifactsDir) paths: - [x] CommonTestRunner Unix/Windows config files - [x] DbgShim.UnitTests Unix/Windows config files - [x] SOS.UnitTests Unix/Windows config files - [x] Remove RepoRootDir from generated Debugger.Tests.Common.txt files - [x] Move free-floating debuggees (Tracee, EventPipeTracee, StackTracee, ExitCodeTracee) under CommonTestRunner/Debuggees - [x] Add ExitCodeTracee (previously missing) - [x] Build and verify the changes work correctly - [x] Remove accidentally included nuget.exe binary file - [x] Fix RepoRootDir references in SOS.cs for lldb tests by using ArtifactsDir paths <!-- START COPILOT CODING AGENT SUFFIX --> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Our general goal is to run the diagnostics tests on Helix. This requires packaging up the built test binaries then running them on a remote machine. > > Currently, the unit tests Debugger.Tests.Config.txt files rely on the $(RepoRootDir). Which is not consistent when moved to another machine. We've already reduced out dependency on this by copying files to the artifacts dir. > > Can you update the Debugger.Tests.Config.txt files in CommonTestRunner, DbgShim.UnitTests, and SOS.UnitTests to no longer user $(RepoRootDir). > > If we need access to the files referenced by $(RepoRootDir), we should copy them to the artifacts dir and have a path relative to the $(ArtifactsDir). </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
Context: dotnet/runtime#124309 (comment) --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Minimum supported runtime is now .NET 8, so `COMPLUS_*` env var fallbacks are unnecessary — all config uses `DOTNET_*`. - **`ProcessRunner.WithRuntimeConfiguration`**: Remove `COMPlus_` fallback (the existing comment explicitly called for this) - **`documentation/FAQ.md`**: Remove stale note about .NET 6 requiring `COMPlus_` prefix Files in `src/shared/` (`clrconfignocache.h`, `resource.h`) are synced from dotnet/runtime and left unchanged — `BFA_BAD_COMPLUS_SIG` refers to COM+ metadata signatures, not env vars. <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/dotnet/diagnostics/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: max-charlamb <44248479+max-charlamb@users.noreply.github.com>
This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260210.1](https://dev.azure.com/dnceng/internal/_build/results?buildId=2900018) ([301121](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/301121)) - **Date Produced**: February 10, 2026 10:29:57 AM UTC - **Commit**: [4bf37ce670528cf2aef4d9b1cd892554b1b02d9d](dotnet/arcade@4bf37ce) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26080.4 to 10.0.0-beta.26110.1][3] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [3]: dotnet/arcade@b0f891c...4bf37ce [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
…#5721) Both ShowLocals switch statements in strike.cpp cast 2-byte values to signed 'short' before assigning to ULONG64, causing sign extension for values >= 0x8000. Change both to 'unsigned short' to match the unsigned types used in cases 1, 4, 8. Fixes #5218. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes #4665. Also, there were some stray characters at the end of some lines that my editor removed, hence the seemingly larger PR than it really is. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The !u command unconditionally called GetILAddress() and aborted if it failed, even when IL interleaving was not needed. This was introduced in commit 6c4dbb3 ("Complete the !u -il SOS command", Sep 2019) which made IL retrieval a hard requirement for all disassembly. This change checks explicitly for a nil metadata token, it also continues with disassembly if we have an md token but fail to get the IL for other reasons. It also now checks for the `-il` parameter before we even try to load the metadata import. This was happening unconditionally before. Fixed some odd wording around dynamic methods. Tested `!u` and `!u -il` on both il stubs and regular methods. Fixes #1907 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Rachel <rachel.jarvi@gmail.com>
## Fix terminal cursor visibility in dotnet-trace collect-linux
### Problem
The `dotnet-trace collect-linux` command hides the terminal cursor
during operation but fails to restore it on exit, leaving users with an
invisible cursor that requires manual restoration via `tput cnorm` or
`reset`.
### Solution
Added cursor visibility restoration in the `finally` block with proper
state tracking to ensure the cursor is restored correctly on all exit
paths.
### Changes Made
1. **CollectLinuxCommand.cs**: Enhanced cursor visibility handling
- Cache original cursor visibility state before hiding
- Only hide cursor when `!Console.IsOutputRedirected`
- Restore original cursor state in `finally` block only if changed
- Prevents changing cursor on early return paths (e.g., `--probe`)
2. **CollectLinuxCommandFunctionalTests.cs**: Updated and improved tests
- Renamed test to
`CollectLinuxCommand_DoesNotChangeCursorVisibility_WhenOutputIsRedirected`
to better reflect behavior
- Converted to theory with `InlineData` to test both `true` and `false`
initial cursor states
- Verifies cursor remains in original state when output is redirected
- Removed brittle line number reference from comment
### Testing
- All 32 CollectLinuxCommand tests passing (31 passed, 1 skipped for
platform)
- Theory now runs twice: once with cursor initially visible, once with
cursor initially hidden
- All cursor visibility tests passing
- No regressions in existing functionality
### Code Changes
```csharp
bool cursorVisibilityChanged = false;
bool originalCursorVisible = false;
// Only hide cursor if output is not redirected
if (!Console.IsOutputRedirected)
{
originalCursorVisible = Console.CursorVisible;
Console.CursorVisible = false;
cursorVisibilityChanged = true;
}
// In finally block:
if (cursorVisibilityChanged)
{
Console.CursorVisible = originalCursorVisible;
}
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>`dotnet-trace collect-linux` leaves terminal cursor
hidden after tracing completes</issue_title>
> <issue_description>### Description
>
> After `dotnet-trace collect-linux` finishes collecting a trace and
exits, the terminal cursor remains hidden. The cursor is not restored to
its visible state on exit, leaving the user with an invisible cursor in
their terminal session.
>
> ### Steps to Reproduce
>
> 1. Open a terminal session.
> 2. Run `dotnet-trace collect-linux -p <pid>` (or any valid
collect-linux invocation).
> 3. Wait for trace collection to complete, or stop it with `Ctrl+C` /
`Enter`.
> 4. Observe that the terminal cursor is no longer visible after the
tool exits.
> 5. The terminal is still functional (typing works), but the cursor is
invisible.
>
> ### Expected Behavior
>
> After `dotnet-trace collect-linux` exits — whether through normal
completion, user-initiated stop, or signal — the terminal cursor should
be restored to its visible state. The tool should ensure terminal state
cleanup happens on all exit paths.
>
> ### Actual Behavior
>
> The cursor remains hidden after the tool exits. Users must manually
restore it by running `tput cnorm` or `reset` to get their cursor back.
>
> ### Additional Context
>
> - The tool likely hides the cursor (e.g., via ANSI escape `\e[?25l`)
during collection for TUI/progress rendering but does not emit the
corresponding show-cursor sequence (`\e[?25h`) on exit.
> - The fix should ensure cursor restoration on all exit paths: normal
exit, `SIGINT`, `SIGTERM`, and any error/panic paths.
> - Consider using a cleanup guard or `defer`/`finally` pattern to
guarantee terminal state is restored regardless of how the tool
exits.</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixes #5706
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: hoyosjs <19413848+hoyosjs@users.noreply.github.com>
Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Add a warning when loading a Linux/macOS dump that was not collected by the .NET runtime's createdump tool. System dumps may be missing memory regions required by SOS commands. The warning is triggered by checking for the absence of the DIAGINFOHEADER signature at the well-known diagnostic page address. This is implemented for both the dotnet-dump analyzer and the native debugger (dbgeng/lldb) host paths. Fixes #5632 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Juan Hoyos <19413848+hoyosjs@users.noreply.github.com>
Move name2ee and token2ee to C# to make them easier to maintain. Implement suggestions in #4993 to reduce the amount of spam output when searching. Fixes #4993. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
When a Linux thread is on an alternate signal stack (e.g. stack overflow handler), SP points to the handler stack while managed objects live on the normal thread stack. The existing code only scans SP + 0xFFFF and misses everything. This change adds GetStackRangeWithAltStackDetection() which collects frame SPs from the managed stack walk, sorts them, and detects a disjoint gap (>4MB) indicating two separate stack regions. When found, both the handler stack and normal thread stack are scanned for objects. macOS uses Mach exceptions rather than sigaltstack, so this scenario does not happen there. No platform check is needed because the frame- based gap detection is harmless when stacks are contiguous. Fixes #4814 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
IL stubs (P/Invoke and Reverse P/Invoke marshaling stubs) have a nil metadata token (0x06000000) and no IL body. The DumpIL command now detects this case early via IsNilToken and prints a clear message instead of the cryptic 'error decoding IL' / 'ilAddr is 0'. Also improved the fallback error message when GetILAddress fails for non-nil tokens. This is the right fix, as IL for stubs is freed after JIT'ing in FreeCompileTimeState. Sometimes they persist if the IL was put on the loader heap for a couple of specific stubs, but it's not worth building a big feature to display these in SOS, so we'll improve the message and be done. Fixes #3005 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes issue #675, but also just improves the amount of symbol lookups we do.
Updates `Microsoft.OneCollect.RecordTrace` from `0.1.32221` to `0.1.33304` in `eng/Versions.props`. - **NativeAOT tracing fix**: The new package version fixes tracing nativeAOT apps with `collect-linux` (dotnet/runtime#123697) - **Logging support**: `0.1.33304` adds `--log-mode`, `--log-filter`, and `--log-path` to `librecordtrace`, which were absent in `0.1.32221`. This unblocks #5709 (adding diagnostic logging to `collect-linux`) <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mdh1418 <16830051+mdh1418@users.noreply.github.com>
Don't truncate if we are asked not to. Fixes #4415 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Customer requested allowing some e_type values (0xFE00-0xFEFF) in the symbol server key generated. This allows key generation for ELF binaries produced by custom toolchains that use the ET_LOOS..ET_HIOS range defined in the ELF spec. There's no way for us to test this, but it's a completely reasonable request and easy/low risk of regression. I suggest we fix it for his internal symbol server. Otherwise close the original bug as won't fix. That's fine by me too. Fixes #5089
This one is a bit outside of my wheelhouse. I had to lean into copilot for building and testing to fix this. This gist explains the overall change, reasoning, and testing: https://gist.github.com/leculver/3b97b312ff5217441e35cf7c57d21a17. The underlying issue does legitimately break tools trying to use SOS within them. The best example for me personally is lldb-dap, hosting lldb as a subprocess does strange things with SOS where the command output comes as events instead of text output like 99.99% of everything else. This change makes LLDB produce the right output in the right circumstances. I generally write the fixes myself, even with llm help, but the following is (unfortunately) copilot generated, and the fix too. But it does work quite well in the tests I built and fixes the issue I have in lldb-dap in my personal project. Fixes #4086. -- SOS commands invoked via SBCommandInterpreter.HandleCommand() were producing console output but returning 0 bytes in SBCommandReturnObject. This broke LLDB Python scripts that capture SOS output programmatically. Root cause: LLDBServices::OutputString() only wrote to file handles via fputs(), completely bypassing the LLDB result object. Fix: Add m_currentResult pointer to LLDBServices. sosCommand::DoExecute sets it before calling the SOS command function and clears it after. OutputString() now writes to the SBCommandReturnObject via Printf() when a result is set, or falls back to fputs() for direct console use. This avoids double output — LLDB auto-prints the result object content after DoExecute returns, so fputs must be skipped when capturing. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Quick fix to add David's requested -stat to threadpool. The formatting code already exists in DumpHeapService, we just turn the print into an enumeration and either dump the stats or the raw work items. Fixes #531 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260223.2](https://dev.azure.com/dnceng/internal/_build/results?buildId=2910551) ([302932](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/302932)) - **Date Produced**: February 23, 2026 12:42:20 PM UTC - **Commit**: [4d898652733deb7dd274237ac06d27ee2ad85b36](dotnet/arcade@4d89865) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26110.1 to 10.0.0-beta.26123.2][3] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [3]: dotnet/arcade@4bf37ce...4d89865 [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
## Summary
When diagnostic tools (dotnet-trace, dotnet-counters, dotnet-stack,
dotnet-dump) run in a sidecar container with `pid: host`, they cannot
find the target process's diagnostic IPC socket. The socket is named
using the container-internal PID (NSpid) and located under
`/proc/{hostPid}/root/{tmpdir}/`, but the tools only look in local
`/tmp/`.
This PR adds cross-namespace IPC resolution to
`Microsoft.Diagnostics.NETCore.Client` so all diagnostic tools work
transparently across PID namespaces. It also adds TMPDIR-aware
resolution for same-namespace processes with a non-default TMPDIR.
Fixes #5694
## Changes
### Commit 1: Core IPC transport support
- Add `TryGetNamespacePid()` — reads `/proc/{pid}/status` NSpid to
detect cross-namespace processes
- Add `GetProcessTmpDir()` — reads `/proc/{pid}/environ` for TMPDIR
(returns `out bool environReadable` for error messaging)
- Parameterize `TryResolveAddress()` — handles both Windows named pipes
and Unix sockets from any search directory
- Simplify `GetDefaultAddress()` flow: resolve one (searchDirectory,
searchPid) pair, single `TryResolveAddress` call
- All Linux-specific methods self-guard, returning safe defaults on
other platforms
### Commit 2: Process enumeration
- Add `GetCrossNamespacePublishedProcesses()` — scans `/proc` for
processes in different namespaces with diagnostic sockets
- Refactor `GetLocalPublishedProcesses()` to be self-contained (handles
its own file listing and exceptions)
- `GetPublishedProcesses()` is a clean union of both methods
- Introduce `ProcPath` constant to avoid hardcoding
### Commit 3: Unit tests
- Extract `TryParseNamespacePid()` and `ParseTmpDir()` for testable
parsing logic
- 9 parsing tests with synthetic data (NSpid variants, TMPDIR parsing)
- 4 behavioral tests with `[ConditionalFact]` (same-namespace detection,
child process TMPDIR reading, platform guards, error paths)
### Commit 4: Address IPC transport review feedback
- Rename `basePath` → `searchDirectory` in `TryResolveAddress`, update
doc comment
- Make `TryResolveAddress` internal for reuse in enumeration
- Change `GetProcessTmpDir` to return `out bool environReadable` for
conditional error messaging
- Narrow try/catch: `DirectoryNotFoundException` for process-exit races,
`UnauthorizedAccessException` for `/proc/{pid}/environ` (owner-only
0400)
- Add `CheckProcessExists` helper (catches `ArgumentException` from
`Process.GetProcessById`)
- Use `Path.Combine` for cross-namespace path construction to handle
relative TMPDIR
- Simplify `GetDefaultAddress` to single `TryResolveAddress` call with
Linux-guarded path resolution
- Add same-namespace different-TMPDIR support: on Linux, use target's
TMPDIR instead of `IpcRootPath`
- Fix error message: reference target's search directory, conditional
TMPDIR hint when environ is unreadable, restore original 108-char socket
path guidance
### Commit 5: Address enumeration review feedback
- Rename `GetCrossNamespacePublishedProcesses` →
`GetProcPublishedProcesses` (now discovers both cross-namespace AND
same-namespace different-TMPDIR)
- Use `TryResolveAddress` instead of `Directory.GetFiles` for robust
socket discovery (handles stale sockets, dsrouter)
- Use `Directory.EnumerateDirectories` for streaming `/proc` iteration
- Use `CheckProcessExists` helper in both enumeration methods
### Commit 6: Update tests for feedback changes
- Handle `hidepid` fallback in child process TMPDIR test (accept default
when environ unreadable)
- Remove `GetDiagnosticSocketSearchPattern` tests (method removed —
`TryResolveAddress` used instead)
## How it works
```
GetDefaultAddress(pid):
1. CheckProcessExists(pid) or throw
2. On Linux:
a. GetProcessTmpDir(pid) → target's TMPDIR (falls back to Path.GetTempPath())
b. TryGetNamespacePid(pid) → cross-namespace?
If yes: searchDirectory = /proc/{pid}/root/{targetTmpDir}, searchPid = nsPid
If no: searchDirectory = targetTmpDir, searchPid = pid
On other platforms:
searchDirectory = IpcRootPath, searchPid = pid
3. TryResolveAddress(searchDirectory, searchPid)
4. Error with platform-specific guidance
```
## Docker Validation
Tested with two containers: target-app (PID 1 inside, host PID 2209) and
tracer (`privileged: true`, `pid: host`).
**Baseline (stock tools v9.0.661903):** All tools fail with
`ServerNotAvailableException`.
| Tool | Command | Result |
|------|---------|--------|
| dotnet-trace | `ps` | ❌ No processes found |
| dotnet-trace | `collect -p 2209` | ❌ ServerNotAvailableException |
| dotnet-trace | `collect-linux --probe -p 2209` | ❌
ServerNotAvailableException |
| dotnet-trace | `collect-linux -p 2209` | ❌ ServerNotAvailableException
|
| dotnet-counters | `ps` | ❌ No processes found |
| dotnet-counters | `monitor -p 2209` | ❌ ServerNotAvailableException |
| dotnet-stack | `report -p 2209` | ❌ ServerNotAvailableException |
| dotnet-dump | `collect -p 2209` | ❌ ServerNotAvailableException |
**Fix (this branch):** All tools work.
| Tool | Command | Result |
|------|---------|--------|
| dotnet-trace | `ps` | ✅ Discovers process |
| dotnet-trace | `collect -p 2209 --duration 5s` | ✅ Trace completed
(404KB nettrace) |
| dotnet-trace | `collect-linux --probe -p 2209` | ✅ Connected
successfully (runtime version check) |
| dotnet-trace | `collect-linux -p 2209 --duration 5s` | ✅ Connected
successfully (runtime version check) |
| dotnet-counters | `ps` | ✅ Discovers process |
| dotnet-counters | `monitor -p 2209 --duration 5` | ✅ Collected
counters |
| dotnet-stack | `report -p 2209` | ✅ Thread stacks printed |
| dotnet-dump | `collect -p 2209` | ✅ Dump written |
> **Note on collect-linux:** The `collect-linux` tests connect
successfully (proving cross-namespace IPC works) but report a runtime
version mismatch because the target runs .NET 10.0.0-preview.7 and
`collect-linux` requires 10.0.0 RTM. This is expected — the baseline
fails with `ServerNotAvailableException` (can't connect at all), while
the fix gets past the connection to the version check.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…_CHANGE_VERSION (#5746) ## Summary Matching PR for dotnet/runtime#125231, which fixes `DefaultCOMImpl::Release()` reference counting bugs in the DAC. ### Changes **1. Bump `SOS_BREAKING_CHANGE_VERSION` from 5 to 6** (`sospriv.h`, `sospriv.idl`) The runtime PR bumps this version. Without updating SOS's copy, users would see a spurious "SOS needs to be upgraded" warning when debugging newer runtimes. **2. Fix `SOSMethodEnum` simulator COM ref counting** (`util.cpp`) The `SOSDacInterface15` simulator's `GetMethodTableSlotEnumerator` had the same bug pattern fixed in the runtime PR — raw pointer assignment without `QueryInterface`, and the null check occurred after the dereference. Fixed to: - Initialize `refCount` to 0 (matching `DefaultCOMImpl` convention) - Use `QueryInterface` to return the interface, properly calling `AddRef` - Check for null before dereferencing the out parameter - Use `delete` on failure (since `QueryInterface` wasn't called at refCount 0) **3. Fix `ISOSMethodEnum` leak in `strike.cpp`** Changed raw `ISOSMethodEnum*` to `ToRelease<ISOSMethodEnum>` so `Release()` is called when the pointer goes out of scope, matching the pattern used everywhere else (e.g., `ToRelease<ISOSHandleEnum>`). Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Summary Matching PR for dotnet/runtime#125231, which fixes `DefaultCOMImpl::Release()` reference counting bugs in the DAC. ### Changes **1. Fix `SOSMethodEnum` simulator COM ref counting** (`util.cpp`) The `SOSDacInterface15` simulator's `GetMethodTableSlotEnumerator` had the same bug pattern fixed in the runtime PR — raw pointer assignment without `QueryInterface`, and the null check occurred after the dereference. Fixed to: - Initialize `refCount` to 0 (matching `DefaultCOMImpl` convention) - Use `QueryInterface` to return the interface, properly calling `AddRef` - Check for null before dereferencing the out parameter - Use `delete` on failure (since `QueryInterface` wasn't called at refCount 0) **2. Fix `ISOSMethodEnum` leak in `strike.cpp`** Changed raw `ISOSMethodEnum*` to `ToRelease<ISOSMethodEnum>` so `Release()` is called when the pointer goes out of scope, matching the pattern used everywhere else (e.g., `ToRelease<ISOSHandleEnum>`). Co-authored-by: Max Charlamb <maxcharlamb@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
On Linux, the in-framework Console.CursorVisible getter always throws PlatformNotSupportedException while the setter works via ANSI escape codes. The collect-linux command was reading Console.CursorVisible to save and restore cursor state, which caused an unhandled exception on every invocation. Since the tests were mocking console, nothing got caught. The getter is unsupported on Linux (the only platform collect-linux runs on) - the most sensible thing was to remove the read entirely and always restore cursor visibility to true on exit.
`Console.KeyAvailable` and `LineRewriter.RewriteConsoleLine` throw exceptions when input and output are redirected. `dotnet-trace collect` works with both redirected and has similar code to what's proposed here.
This record-trace version should contain the rbp chain walking fix and nested container nspid resolution fix.
… events in collect-linux (#5756) `dotnet-trace collect-linux` creates provider flags with `new_dotnet_provider_flags()` which defaults callstacks to false. This causes `perf_event` to skip callchain capture for .NET runtime events (exceptions, GC, etc.), resulting in stacks that only show the kernel's `user_events_write_core` frame with no user-space context. This adds `with_callstacks()` to the provider flags so `perf_event` captures callchains for runtime events. Without this fix, the exception stacks view in PerfView shows: ``` Name ROOT + Process32 dotnet-sample (2672) Args: dotnet-sample + Thread (2683) + BROKEN + vmlinux!user_events_write_core.isra.0 + Throw() ``` With this fix, the physical call stack is captured including resolved runtime frames: ``` Name ROOT + Process32 dotnet-sample (9808) Args: dotnet-sample + Thread (9819) + BROKEN + libcoreclr.so!DispatchManagedException(Object*, _CONTEXT*, _EXCEPTION_RECORD*) + libcoreclr.so!DispatchCallSimple(unsigned long*, unsigned int, unsigned long, unsigned int) + libcoreclr.so!CallDescrWorkerInternal + ManagedModule!EH.DispatchEx |+ libcoreclr.so!SfiInit | + libcoreclr.so!SfiInitWorker(StackFrameIterator*, _CONTEXT*, bool, bool*) | + libcoreclr.so!ETW::ExceptionLog::ExceptionThrown(CrawlFrame*, int, int) | + libcoreclr.so!EventPipeWriteEventExceptionThrown_V1 | + libcoreclr.so!ep_write_event(_EventPipeEvent*, unsigned char*, unsigned int, unsigned char const*, unsigned char const*) | + libcoreclr.so!write_event_2(Thread*, _EventPipeEvent*, _EventPipeEventPayload*, unsigned char const*, unsigned char const*, Thread*, _EventPipeStackContents*) | + libcoreclr.so!ep_session_write_event(_EventPipeSession*, Thread*, _EventPipeEvent*, _EventPipeEventPayload*, unsigned char const*, unsigned char const*, Thread*, _EventPipeStackContents*) | + libc.so.6!writev | + vmlinux!entry_SYSCALL_64_after_hwframe | + vmlinux!do_syscall_64 | + vmlinux!x64_sys_call | + vmlinux!__x64_sys_writev | + vmlinux!do_writev | + vmlinux!vfs_writev | + vmlinux!do_iter_write | + vmlinux!do_iter_readv_writev | + vmlinux!user_events_write_iter | + vmlinux!user_events_write_core.isra.0 | + Throw() ``` Note: collect-linux captures the physical CPU call stack at the tracepoint fire site, which includes runtime internals. The clean managed-only stacks shown by dotnet-trace collect (e.g., `ExceptionWorker` -> `ThrowNested` -> `Throw`) require the runtime's internal managed stack walker, which is not yet included in user_events tracepoint data. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…failure (#5751) Investigating #5750 The test fails on Ubuntu 22.04 CI with environ readable but TMPDIR not matching the custom value. Add diagnostic output to the assertion messages to capture: environ byte size, env var count, raw TMPDIR entry, parent TMPDIR, ProcessStartInfo TMPDIR, file permissions, child exit state, current user, and first 200 bytes of environ content. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…adDotNetExtensions (#5759) ## Summary Contributes to #5757 CDB 10.0.26100.1 introduced `SecureLoadDotNetExtensions` which verifies digital signatures of DAC DLLs before loading them. Both the .NET Framework `mscordacwks.dll` (from local Framework directory and symbol server) and servicing .NET Core DAC DLLs fail this verification, causing 16 test failures across all Windows legs: ``` Failed to verify signature of file: C:\Windows\Microsoft.Net\Framework64\v4.0.30319\mscordacwks.dll Error code - 0x000021BE Debugger.Settings.EngineInitialization.SecureLoadDotNetExtensions is enabled, set to false to disable. Failed to load data access module, 0x80004002 ``` ## Root Cause The test infrastructure conditionally enables `SecureLoadDotNetExtensions=true` for non-nightly, non-private builds. CDB then rejects the DAC DLLs because their signatures cannot be verified: - `.NET Framework DAC` — `mscordacwks.dll` from `C:\Windows\Microsoft.Net\Framework64\v4.0.30319\` and from the symbol server - `Servicing .NET Core DAC` — for .NET 8.0 servicing runtimes This affects three test categories: - **13 `desktop.cli` tests** — desktop CLR DAC signature verification fails - **2 `projectk.sdk.prebuilt` tests** (DualRuntimes) — desktop CLR portion of dual-runtime dump fails - **1 `projectk.cli.singlefile` test** (StackAndOtherTests) — .NET 8.0 servicing DAC fails ## Changes All changes are in `SOS.cs` — disable the affected tests until the CDB signing issue is resolved: 1. **Exclude desktop CLR configurations** from `SOS.Configurations` — filters out `IsDesktop` configs that rely on `mscordacwks.dll` 2. **Skip `StackAndOtherTests`** for single-file on Windows — .NET 8.0 servicing DAC signature verification fails under CDB 3. **Skip `DualRuntimes`** on Windows — desktop CLR DAC portion of dual-runtime dump fails ## Impact - Disables **16 tests** blocked by CDB DAC signature verification failures - Tests can be re-enabled once the signing issue with the CDB package is resolved (tracked by #5757) - Test-only change — no product code or test infrastructure changes --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260318.1](https://dev.azure.com/dnceng/internal/_build/results?buildId=2929531) ([306738](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/306738)) - **Date Produced**: March 18, 2026 10:20:24 AM UTC - **Commit**: [3907f62e877e105b6196b1bd9c309203d6362a0a](dotnet/arcade@3907f62) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26123.2 to 10.0.0-beta.26168.1][1] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [1]: dotnet/arcade@4d89865...3907f62 [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
https://dev.azure.com/dnceng-public/public/_build/results?buildId=1348854 For an unknown reason, the cDAC SOS test runs have better !clrstack output than that of the DAC in these three tests - the DAC output resolves the bottom of the stack to the start of the method, whereas the cDAC is able to resolve the exact line. The tests currently expect the start of the method, so they fail on the cDAC. This just loosens the tests to accept either the exact line or the start of the method.
OneCollect has some fixes that will improve `dotnet-trace collect-linux`'s tracing experience. - microsoft/one-collect#239 - microsoft/one-collect#240
…s, literal output assertions (#5773) - [x] Address review comment 1: refactor `ProgressCallback` as optional method parameter on `EnumerateFilteredObjects` (remove from `HeapWithFilters` class property) - [x] Address review comment 2: rewrite byte-tracking in `EnumerateFilteredObjects` to use segment position (`obj.Address - segment.Start`, 16KB threshold, segment start/end callbacks) - [x] Refactor `ProgressReporter` to be the timed console writer registered as callback (takes `Action<string>` writeMessage, receives `(scannedBytes, totalBytes)` via `Report` method) - [x] Update `DumpHeapCommand` and `VerifyHeapCommand` to use new API - [x] Update `ProgressReporterTests` to match new `ProgressReporter` API (7/7 tests pass) <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > Modify Dan Moseley's PR #5763 (branch: danmoseley:heap-progress) to do the following: > > 1. Add a flag to opt out of progress reporting for heap enumeration. > 2. Update the unit test cases so that they validate literal output from progress lines, rather than simply inferring correctness using text.Contains("5"). > 3. Refactor progress timing tests to use TimeProvider, so that the test does not rely on sleep() or time delays, and instead deterministically validates timing. > > Requirements: > - Show the full `git diff` of changes before pushing to the PR branch. > - Do not push any changes until the user explicitly approves after seeing the diff. > > The following is the prior conversation context from the user's chat exploration (may be truncated): > > User: Can you push commits to this PR? > > Assistant: **Yes, you should be able to push commits to this PR.** Here's why: > > 1. **`maintainer_can_modify` is `true`** — The PR author (@danmoseley) enabled "Allow edits from maintainers" when creating this PR from their fork (`danmoseley/diagnostics` → `dotnet/diagnostics`). > > 2. **You have write access** — As long as you have push/write permissions to the base repository (`dotnet/diagnostics`), GitHub allows you to push commits directly to the PR's head branch (`heap-progress` on `danmoseley/diagnostics`). > > You can push to the branch by adding the fork as a remote and pushing to the `heap-progress` branch: > > ```bash > git remote add danmoseley https://github.com/danmoseley/diagnostics.git > git push danmoseley HEAD:heap-progress > ``` > > This is documented in GitHub's guide on [Committing changes to a pull request branch created from a fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork). > > User: Do you have permissions to modify this PR? > > Assistant: I'm waiting for your confirmation to proceed with the tool call that was just proposed. > > User: @Copilot Accepted Confirmation: Confirm agent session > > Assistant: I don't have the ability to directly check my own permissions on a repository. However, I've kicked off a task that will attempt to interact with the PR, which will effectively test whether I have write access: > > ````list type="task" > data: > - title: '[WIP] Check push permissions to PR #5763' > repository: dotnet/diagnostics > url: https://github.com/copilot/tasks/pull/PR_kwDOB4aLFs7MAicv?session_id=88a58d80-0bba-4b9d-bf31-fcfdb05e5cf0 > state: queued > > ```` > > That said, to answer your question more directly: **I don't know for certain whether I (Copilot) have write permissions to `dotnet/diagnostics`**. That depends on: > > 1. **Whether GitHub Copilot is installed** on the `dotnet/diagnostics` repository (or the `dotnet` org) with write permissions. > 2. **Whether the org/repo settings** allow Copilot to push to forks via `maintainer_can_modify`. > > If the task above fails with a permissions error, that will confirm I don't have the necessary access. In that case, you (hoyosjs) would need to push the commits yourself, assuming you have write access to `dotnet/diagnostics`. > > User: Modify Dan Moseleys pr to: > > - add a flag to opt out of progress report > -we actually see some literal output in the test cases rather than just infering the whole thing is good from text.Contains("5") > - use TimeProvider to validate the progress part without relying on sleep() in the test (or the current state that doesn't actually validate progress timing) > > Show me the diff before pushing to the PR > > Assistant: I'll prepare a diff that modifies Dan Moseley's PR as you requested—adding a flag to opt out of progress reporting, improving test assertions to check the actual output, and refactoring timing verification to use TimeProvider instead of sleep. > > Once the changes are ready, I will show you the complete diff so you can review it before anything is pushed. > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> *This pull request was created from Copilot chat.* > <!-- START COPILOT CODING AGENT TIPS --> --- 💬 Send tasks to Copilot coding agent from [Slack](https://gh.io/cca-slack-docs) and [Teams](https://gh.io/cca-teams-docs) to turn conversations into code. Copilot posts an update in your thread when it's finished. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Dan Moseley <danmose@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: hoyosjs <19413848+hoyosjs@users.noreply.github.com> Co-authored-by: noahfalk <6243776+noahfalk@users.noreply.github.com>
This pull request updates the following dependencies [marker]: <> (Begin:39a983c9-68a4-46ae-bbba-6795aab4810d) ## From https://github.com/dotnet/arcade - **Subscription**: [39a983c9-68a4-46ae-bbba-6795aab4810d](https://maestro.dot.net/subscriptions?search=39a983c9-68a4-46ae-bbba-6795aab4810d) - **Build**: [20260327.7](https://dev.azure.com/dnceng/internal/_build/results?buildId=2937446) ([308097](https://maestro.dot.net/channel/8394/github:dotnet:arcade/build/308097)) - **Date Produced**: March 27, 2026 3:14:28 PM UTC - **Commit**: [62dc2defffeadabf6761a9ed7e142692107330c0](dotnet/arcade@62dc2de) - **Branch**: [release/10.0](https://github.com/dotnet/arcade/tree/release/10.0) [DependencyUpdate]: <> (Begin) - **Dependency Updates**: - From [10.0.0-beta.26168.1 to 10.0.0-beta.26177.7][1] - Microsoft.DotNet.Arcade.Sdk - Microsoft.DotNet.CodeAnalysis [1]: dotnet/arcade@3907f62...62dc2de [DependencyUpdate]: <> (End) [marker]: <> (End:39a983c9-68a4-46ae-bbba-6795aab4810d) Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
…mpDir tests (#5782) There's a short period of time between `Process.Start` returning, and the pinvokes into fork and exec. During this period, the target might not have a populated environ procfs file. Loop with a sleep and try again.
…bing (#5705) ## Summary Handle exceptions in `CollectLinuxCommand` process probing to gracefully handle processes that cannot be resolved or connected to. Builds on #5778 (Juan's simple catch-and-skip fix) by adding structured error reporting and covering an additional failure mode (`IOException` from mid-response disconnection). ## Problem When `collect-linux --probe` enumerates all published .NET processes, several exceptions can occur between discovery and probing: - **`ServerNotAvailableException`** — diagnostic socket not found (process exited before connection) - **`IOException`** ("Connection reset by peer") — process exited mid-IPC response (#5778's `catch (DiagnosticToolException or DiagnosticsClientException)` does not cover this) - **`UnsupportedCommandException`** — runtime too old to support `GetProcessInfo` - **`DiagnosticToolException`** — process exited between `GetPublishedProcesses` and `ResolveProcess` Previously (before #5778), these propagated to the outer `catch (Exception)`, printing a full stack trace to stderr and returning `UnknownError`. #5778 added a catch-and-skip for `DiagnosticToolException` and `DiagnosticsClientException`, but silently drops the processes and doesn't cover `IOException`. ## What this PR adds on top of #5778 1. **Structured probe results** — `UserEventsProbeResult` enum (`Supported`, `NotSupported`, `ConnectionFailed`) replaces boolean, enabling distinct handling per outcome 2. **"Could not be probed" reporting** — instead of silently skipping, processes that fail probing are reported in a dedicated section (console) or as `unknown` (CSV), so users know these processes existed 3. **`IOException` catch** — covers the "Connection reset by peer" scenario observed in CI that #5778 misses 4. **Single-process graceful handling** — `--probe -p PID` and `collect-linux -p PID` now handle connection failures with clean error messages instead of stack traces 5. **`UnsupportedCommandException` handling** — ancient runtimes that don't support `GetProcessInfo` are reported as `NotSupported` instead of crashing 6. **Preserved original error messages** — argument validation errors (`-1 is not a valid process ID`, `Only one of --name or --process-id`, etc.) still propagate with their original specific messages and `ArgumentError` return code ## Behavior **Non-probe mode** (`dotnet-trace collect-linux -p <pid>`): - Connection failure: `[ERROR] Unable to connect to process '<name> (<pid>)'. The process may have exited, or it doesn't have an accessible .NET diagnostic port.` → `TracingError` - Argument errors: original messages preserved → `ArgumentError` **Single-process probe mode** (`dotnet-trace collect-linux --probe -p <pid>`): - Connection failure: `Could not probe process '<name> (<pid>)'. The process may have exited, or it doesn't have an accessible .NET diagnostic port.` → `Ok` - Argument errors: original messages preserved → `ArgumentError` **Multi-process probe mode** (`dotnet-trace collect-linux --probe`): - Console output shows ".NET processes that could not be probed" section when applicable - CSV output includes `unknown` value for unprobed processes - Processes that exit during name resolution are silently skipped - Processes that exit during probing are reported with name in the "could not be probed" section --------- Co-authored-by: mdh1418 <mitchhwang1418@gmail.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Mitchell Hwang <16830051+mdh1418@users.noreply.github.com>
…sWriter (#5771) When CursorTop is 0 (e.g., in environments where cursor positioning isn't available), LineToClear was set to -1, causing SetCursorPosition to throw ArgumentOutOfRangeException on progress callbacks. Extract the progress display concern from OutputHandler into a nested ProgressWriter class that: - Probes console capability on first Update() call - Interactive: rewrites status line in-place with 1s throttle - Non-interactive: prints a static message once, silently no-ops after - Owns LineRewriter and LineToClear internally OutputHandler's status block reduces to progressWriter.Update(), fully decoupling it from LineRewriter. Matches CollectCommand's pattern of probing capability upfront and gating on it. Also adds bounds validation to MockConsole.SetCursorPosition and a regression test for the CursorTop=0 case. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…indows (#5593) ## Summary Fixes #5020 - `DiagnosticsClient.WriteDump()` now correctly handles dump file paths containing spaces on Windows. ## Problem When calling `WriteDump()` with a path containing spaces on Windows, the operation would fail with the error: ``` [createdump] The pid argument is no longer supported ``` This occurred because the runtime's `createdump` utility on Windows was parsing the unquoted path as multiple command-line arguments. For example, a path like `C:\my dumps\dump.dmp` would be split into `C:\my` and `dumps\dump.dmp`, causing the latter part to be misinterpreted as additional arguments. This issue is specific to Windows due to how the runtime builds the command line for createdump. Linux and macOS do not have this problem. ## Solution The fix wraps the dump path in quotes before sending it to the runtime **on Windows only**: - Paths are now automatically quoted on Windows: `C:\my dumps\dump.dmp` → `"C:\my dumps\dump.dmp"` - Logic prevents double-quoting if the path is already quoted (handles the workaround some users may have implemented) - Non-Windows platforms (Linux/macOS) are unaffected and paths are passed through unchanged ## Changes Modified the two `CreateWriteDumpMessage` method overloads in `DiagnosticsClient.cs` to: 1. Check the platform using `RuntimeInformation.IsOSPlatform(OSPlatform.Windows)` 2. Quote the dump path before serialization only on Windows 3. Check if the path is already quoted to avoid double-quoting ```csharp // Quote the path to handle spaces correctly in createdump on Windows only // Only add quotes if the path is not already quoted // This is only needed on Windows where the runtime builds the command line for createdump string pathToUse = dumpPath; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { pathToUse = dumpPath.StartsWith("\"") && dumpPath.EndsWith("\"") ? dumpPath : $"\"{dumpPath}\""; } ``` ## Testing Manually verified the quoting logic handles: **On Windows:** - ✅ Paths without spaces: `C:\dumps\dump.dmp` → `"C:\dumps\dump.dmp"` - ✅ Paths with spaces: `C:\my dumps\dump.dmp` → `"C:\my dumps\dump.dmp"` (fixes the issue) - ✅ Already quoted paths: `"C:\my dumps\dump.dmp"` → `"C:\my dumps\dump.dmp"` (no double-quoting) **On Linux/macOS:** - ✅ All paths are passed through unchanged (no quoting applied) The fix is minimal, backward compatible, platform-specific, and addresses the reported issue while maintaining compatibility with the workaround mentioned in the issue. > [!WARNING] > > Fixes #5020 <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>Diagnostics client fails to create dump when path has spaces</issue_title> > <issue_description>### Description > > .NET diagnostics client fails when path to dump file has spaces in it. This reproduces both on net8 and net9, and fails with error: > > [createdump] The pid argument is no longer supported [coming from here](https://grep.app/search?q=The%20pid%20argument%20is%20no%20longer%20supported) > > It can be fixed by wrapping the path to extra `""`. > > I am using the latest version of the client package. > > ### Reproduction Steps > > ```csproj > <!-- file DumpError.csproj --> > <Project Sdk="Microsoft.NET.Sdk"> > > <PropertyGroup> > <OutputType>Exe</OutputType> > <TargetFramework>net8.0</TargetFramework> > <ImplicitUsings>enable</ImplicitUsings> > <Nullable>enable</Nullable> > </PropertyGroup> > > <ItemGroup> > <PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.547301" /> > </ItemGroup> > > </Project> > > ``` > > ```cs > // file Program.cs > using Microsoft.Diagnostics.NETCore.Client; > using System.Diagnostics; > > public static class Program > { > public static int Main(string[] args) > { > if (args.Length > 0 && args[0] == "--hang") > { > Thread.Sleep(int.MaxValue); > } > > var path = Path.Combine(AppContext.BaseDirectory, "DumpError.exe"); > Process? process = null; > try > { > process = Process.Start(path, "--hang"); > var diagnosticClient = new DiagnosticsClient(process.Id); > Thread.Sleep(1_000); > diagnosticClient.WriteDump(DumpType.Full, $"{Path.Combine(AppContext.BaseDirectory, $"my dump with spaces {Stopwatch.GetTimestamp()}.dmp")}", logDumpGeneration: true); > } > finally > { > process?.Kill(); > } > > return 0; > } > } > > ``` > > > > ### Expected behavior > > Spaces are correctly escaped and my dump is written to disk. > > ### Actual behavior > > [createdump] The pid argument is no longer supported error is shown and dump is not written. > > ### Regression? > > No. > > ### Known Workarounds > > Add quotes around the path, or move to folder without spaces. > > ### Configuration > > Win 11, 8.0.110, but reproduces on latest net9 as well. > > ### Other information > > _No response_</issue_description> > > <agent_instructions>See what you can do to support spaces in the path when generating a dump file calling WriteDump.</agent_instructions> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> Fixes #5020 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: steveisok <471438+steveisok@users.noreply.github.com>
…5787) The CollectCommandFunctionalTests substitute a MemoryStream for the output file stream, so the trace file is never created on disk. The interactive status-printing path is non-deterministic in these tests because the MemoryStream-backed session completes near-instantly, and whether the status line fires before the loop exits depends on thread scheduling. When it does fire, FileInfo.Length throws because the file does not exist. Set IsOutputRedirected=true on MockConsole to disable the status path. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
noahfalk
approved these changes
Apr 2, 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.
Copilot aided release notes for user facing changes
Breaking Changes
dotnet-dump / SOS
New features:
-allflag toDumpMTcommand #5701)Bug fixes:
dotnet-trace / collect-linux
dotnet-counters
Diagnostic Tools (general)
Libraries