Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add --crash-report option to the CrashDump extension - #8191

Merged
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report
May 18, 2026
Merged

Add --crash-report option to the CrashDump extension#8191
Amaury Levé (Evangelink) merged 17 commits into
mainfrom
copilot/feature-generate-crash-report

Conversation

CopilotAI commented May 13, 2026

Copy link
Copy Markdown
Contributor

New Feature

What does this feature do?

The CrashDump extension can now ask the .NET runtime to generate JSON crash reports in addition to, or instead of, a dump. This makes crash triage lighter-weight in CI, especially for environments where full dump collection is expensive or impractical.

A single composable flag --crash-report was chosen over the original two-flag (--crashreport + --crashreport-only) design: one flag = one artifact type, the option can be combined freely with --crashdump, and no awkward mutual-exclusion validation is needed.

Why is this feature needed?

DOTNET_EnableCrashReport and DOTNET_EnableCrashReportOnly are already available in the runtime, but the MTP CrashDump extension only exposed dump generation. Surfacing crash reports gives a cheaper diagnostic path and improves crash investigation on machines where developers cannot inspect native dumps directly.

Implementation details

  • CLI surface

    • Added --crash-report (kebab-case, matching the broader MTP CLI convention such as --results-directory, --diagnostic-output-directory, etc.)
    • Behavior matrix:
      • --crashdump → dump only
      • --crash-report → crash report only
      • --crashdump --crash-report → dump + crash report
    • On Windows, --crash-report is rejected at command-line validation time because the .NET runtime ignores DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly on Windows (see dotnet/runtime#80191). The error message points users to --crashdump as the alternative.
  • Runtime configuration

    • Wires the new option to the runtime environment variables:
      • --crashdump --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReport=1
      • --crash-reportDOTNET_DbgEnableMiniDump=1 + DOTNET_EnableCrashReportOnly=1 (createdump still needs MiniDump activation to emit the report)
  • Artifacts and user-visible behavior

    • Added crash report artifact discovery/publishing for *.crashreport.json
    • The crash banner is now driven by what was actually written to disk (per-artifact generated / could not find messaging), so it no longer claims success for an artifact the runtime did not emit.
    • Updated help text and PACKAGE.md to describe the new option and the Windows limitation.
  • Platform fix (deterministic option ordering)

    • Microsoft.Testing.Platform now sorts CLI options for --help / --info using StringComparer.Ordinal instead of the culture-aware default. Without this, the relative order of --crash-report vs --crashdump differed between .NET Framework (word sort ignores -) and .NET (Core) (ordinal-like ICU sort), which would make the help/info acceptance tests non-deterministic across TFMs.
  • Coverage

    • Unit coverage for --crash-report alone, --crash-report combined with --crashdump, and the Windows-only validation rejection.
    • Acceptance coverage for:
      • --crashdump --crash-report (dump + report, Linux/macOS only)
      • --crash-report alone with default name (report only, Linux/macOS only)
      • --crash-report with --crashdump-filename (report only with custom name, Linux/macOS only)
      • --crash-report on Windows → fails with the platform-limitation error
    • Updated --help / --info expectations for the new CLI option ordering.

Example

# Generate a dump and a JSON crash report (Linux/macOS)
dotnet test -- --crashdump --crash-report
# Generate only a JSON crash report (Linux/macOS)
dotnet test -- --crash-report
# On Windows, --crash-report is rejected (use --crashdump):
dotnet test -- --crashdump

CopilotAI self-assigned this May 13, 2026
CopilotAI review requested due to automatic review settings May 13, 2026 17:02
CopilotAI removed the request for review from CopilotMay 13, 2026 17:02
CopilotAI linked an issue May 13, 2026 that may be closed by this pull request
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 13, 2026 17:23
CopilotAI changed the title [WIP] Add feature to generate crash report for .NET 6.0 and 7.0Add crash report support to the CrashDump extensionMay 13, 2026
@Evangelink
Amaury Levé (Evangelink) marked this pull request as ready for review May 14, 2026 14:59
CopilotAI review requested due to automatic review settings May 14, 2026 14:59

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends the CrashDump MTP extension with new --crashreport and --crashreport-only options that wire the test host runtime variables DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly and publish the resulting *.crashreport.json as artifacts.

Changes:

  • New CLI options with mutual-exclusion validation (--crashreport requires --crashdump; --crashreport-only excludes the others).
  • Environment variable provider sets the new runtime variables (and keeps DbgEnableMiniDump for --crashreport-only); lifetime handler emits new "dump only / report only / dump + report" messages and publishes crash report artifacts.
  • New resx/xlf entries, PACKAGE.md doc update, unit/acceptance/help-info test coverage for the new options.
Show a summary per file
FileDescription
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineOptions.csAdds option name constants for the two new flags.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.csRegisters new options and adds combined-options validation via chained ternary.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.csSets/validates DOTNET_EnableCrashReport(Only) and conditionalizes DbgEnableMiniDump.
src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.csPicks crash message variant; publishes .crashreport.json artifacts in addition to dumps.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/CrashDumpResources.resxNew resource strings for descriptions, errors, and crash messages.
src/Platform/Microsoft.Testing.Extensions.CrashDump/Resources/xlf/*.xlfAuto-added state="new" entries mirroring the resx additions across all locales.
src/Platform/Microsoft.Testing.Extensions.CrashDump/PACKAGE.mdDocuments new crash report capabilities.
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.csAdds unit tests for valid/invalid combinations of the new flags.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.csAcceptance tests for dump+report, report-only, and --crashreport without --crashdump.
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.csUpdates expected help/info output to include the new options.

Copilot's findings

  • Files reviewed: 22/22 changed files
  • Comments generated: 3

Amaury Levéand others added 2 commits May 14, 2026 20:19
…shDump tests/code
- Reorder --crashreport / --crashreport-only after --crashdump-type in the
Help and Info expectations to match the platform's alphabetical ordering
(CommandLineHandler.PrintOptionsAsync OrderBy(option.Name)).
- Refactor CrashDump option validation into explicit if-statements for clarity.
- Rename EnableMiniDumpValue -> EnabledValue (now reused for crash report vars).
- Make CrashReportOnly_CustomDumpName_CreateOnlyCrashReport robust on Windows by
doing an exact filename comparison instead of relying on Directory.GetFiles
pattern matching, which can match 'customdumpname.dmp.crashreport.json'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert the validation refactor, EnabledValue rename, and the Windows-safe
filename check in CrashReportOnly_CustomDumpName_CreateOnlyCrashReport.
The HelpInfoAllExtensionsTests ordering fix is preserved.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 14, 2026 18:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

Comments suppressed due to low confidence (1)

src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs:1

  • Mirror of the existing dump-fallback path: if Path.GetDirectoryName(expectedCrashReportFile) returns an empty string (when the dump file pattern is just a filename with no directory component), Directory.GetFiles("", ...) will throw ArgumentException. The pre-existing dump branch has the same issue, but consider falling back to the current directory or skipping the scan when the directory is empty so the new code path doesn't introduce another instance of the same brittleness.
// Copyright (c) Microsoft Corporation. All rights reserved.
  • Files reviewed: 22/22 changed files
  • Comments generated: 8

- CrashDumpCommandLineProvider: replace chained ternary with explicit
if-statements for clarity and easier extension.
- CrashDumpEnvironmentVariableProvider: rename EnableMiniDumpValue to
EnabledValue since it's now reused for the crash report environment
variables (DOTNET_EnableCrashReport / DOTNET_EnableCrashReportOnly).
- CrashReportOnly_CustomDumpName_CreateOnlyCrashReport: do an explicit
filename comparison instead of relying on Directory.GetFiles' pattern
matching, which on Windows can also match
'customdumpname.dmp.crashreport.json' for the literal pattern
'customdumpname.dmp'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 14, 2026 19:01

CopilotAI commented May 14, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in d68feac. I covered the remaining CrashDump review feedback: validation precedence/coverage, resource quoting and XLF sync, crash report minidump wiring, crash report suffix constants, environment validation deduplication, and the acceptance test rename.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 3

{
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile)), cancellationToken).ConfigureAwait(false);
foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp"))
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.dmp fallback enumeration is now filtered with Path.GetExtension(f).Equals(".dmp", StringComparison.OrdinalIgnoreCase) so a customdumpname.dmp.crashreport.json (or any other extension that merely starts with .dmp) cannot leak through (CrashDumpProcessLifetimeHandler.cs:109-110).

Comment on lines 48 to +52
public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
=> ValidationResult.ValidTask;
=> commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName)
&& RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? ValidationResult.InvalidTask(CrashDumpResources.CrashReportNotSupportedOnWindowsErrorMessage)
: ValidationResult.ValidTask;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the --crash-report option description in CrashDumpResources.resx:182-184 and PACKAGE.md:18,24 both explicitly state "Requires .NET 7+ when used alone; .NET 6+ when combined with --crashdump" and call out "This runtime requirement is not enforced by the tool: on unsupported runtimes no crash report will be emitted." That meets the "at minimum, the help text should make clear" bar. Surfacing a warning at runtime would require detecting the runtime version up-front, which we deliberately punted as out of scope for the initial PR.

string optionNameIndent = new(' ', indentLevel * 2);
string optionInfoIndent = new(' ', (indentLevel + 1) * 2);
foreach (CommandLineOption option in options.OrderBy(x => x.Name))
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted. The sort change in CommandLineHandler.cs:113-116 was subsequently softened to StringComparer.OrdinalIgnoreCase (per r3258181853) so casing differences also sort stably. The visible-order change will be picked up by the next platform release notes when that bundle is assembled — there's no standalone changelog file in this repo to update for an in-flight MTP change.

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Re-checked the review comments on the current branch. No additional changes were needed: 9192db1 is included in the branch and already addresses the CrashDump feedback. Revalidated the CrashDump build and focused unit tests successfully.

- CrashDumpProcessLifetimeHandler: filter the *.dmp fallback enumeration by
exact extension (case-insensitive) so Windows 8.3 short-name matching cannot
re-publish *.dmp.crashreport.json files as dump artifacts.
- CrashReportOptionDescription: explicitly state that the .NET runtime
requirement is not enforced by the tool and that no report is emitted on
unsupported runtimes.
- CommandLineHandler: document the rationale for using StringComparer.Ordinal
for option ordering (deterministic across TFMs, user-visible).
- Updated HelpInfoAllExtensionsTests expectations and regenerated XLF files
for the CrashDump resource change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
CopilotAI review requested due to automatic review settings May 18, 2026 10:26

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 23/23 changed files
  • Comments generated: 7

{
await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)).ConfigureAwait(false);
await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashReportFile, expectedCrashReportFile, CrashReportFileSearchPattern)), cancellationToken).ConfigureAwait(false);
foreach (string crashReportFile in Directory.GetFiles(Path.GetDirectoryName(expectedCrashReportFile)!, CrashReportFileSearchPattern))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the *.crashreport.json fallback now filters with f.EndsWith(CrashReportFileExtension, StringComparison.OrdinalIgnoreCase) so a foo.crashreport.jsonbak (or any 8.3 short-name alias) cannot be re-published as a crash report (CrashDumpProcessLifetimeHandler.cs:130-131).

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the UTF-8 BOM is back on CrashDumpEnvironmentVariableProvider.cs:1 (matching every other C# file in the project).

Comment on lines +113 to +116
// Use StringComparer.Ordinal so the option ordering is deterministic across TFMs
// (the culture-aware default sorts '-' differently between .NET Framework and .NET (Core)).
// Note: this affects the visible order of options in `--help` / `--info` output.
foreach (CommandLineOption option in options.OrderBy(x => x.Name, StringComparer.Ordinal))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — switched from StringComparer.Ordinal to StringComparer.OrdinalIgnoreCase (CommandLineHandler.cs:116) so casing differences also sort stably, and added an inline comment calling out that this affects the visible order of options in --help/--info. The release-notes mention will be picked up when the next platform release bundle is assembled.

- **Crash report collection**: optionally emits a lightweight JSON crash report to help diagnose crashes without uploading a full dump (Linux/macOS only — see [dotnet/runtime#80191](https://github.com/dotnet/runtime/issues/80191))
- **Post-mortem debugging**: collected dumps can be analyzed with tools like Visual Studio, WinDbg, or `dotnet-dump`
- **Cross-platform**: supported on Windows, Linux, and macOS. Note that dumps collected on macOS can only be analyzed on macOS
- **Cross-platform**: crash dumps are supported on Windows, Linux, and macOS (dumps collected on macOS can only be analyzed on macOS). Crash reports are currently only supported on Linux and macOS.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96PACKAGE.md:18 and PACKAGE.md:24 both call out the runtime version requirement: "requires .NET 7+ when used alone or .NET 6+ when combined with --crashdump".

Comment on lines +84 to +87
bool dumpFileFound = generateDump && File.Exists(expectedDumpFile);
bool crashReportFileFound = generateCrashReport && File.Exists(expectedCrashReportFile);

string? processCrashedMessage = (dumpFileFound, crashReportFileFound) switch

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96 — the variables are now dumpArtifactProduced / crashReportArtifactProduced (CrashDumpProcessLifetimeHandler.cs:84-85), with an inline comment clarifying "what was actually produced, not what was requested".

Comment on lines +86 to +88
[TestMethod]
[OSCondition(ConditionMode.Include, OperatingSystems.Windows, IgnoreMessage = "Validates Windows-specific error for --crash-report")]
public async Task CrashReport_OnWindows_FailsWithValidationError()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Already addressed in 8763b96CrashDump_WithCrashReport_OnWindows_FailsWithValidationError at CrashDumpTests.cs:97-106 runs --crashdump --crash-report and asserts ExitCode.InvalidCommandLine plus the not supported on Windows message.

Comment on lines +71 to +72
bool generateDump = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashDumpOptionName);
bool generateCrashReport = _commandLineOptions.IsOptionSet(CrashDumpCommandLineOptions.CrashReportOptionName);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #8328 — the generic CrashDumpProcessCrashed banner now reads "Test host process with PID '{0}' crashed but the expected diagnostic artifact(s) were not produced". Since IsEnabledAsync guarantees at least one of --crashdump / --crash-report is set whenever this handler runs, reaching the (false, false) branch always means an expected artifact was not produced, so the more informative wording is always accurate. XLF files regenerated in the same commit.

@Evangelink

Copy link
Copy Markdown
Member

Copilot address review comments

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:28
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
CopilotAI requested review from Copilot and removed request for CopilotMay 18, 2026 13:29

CopilotAI commented May 18, 2026

Copy link
Copy Markdown
ContributorAuthor

Copilot address review comments

Addressed in 9ef5281 with follow-up clarification in 717f1e5. I tightened the crash report fallback filtering, restored the C# BOM, updated runtime docs, switched option ordering to OrdinalIgnoreCase, and added Windows coverage for --crashdump --crash-report validation.

@Evangelink
Amaury Levé (Evangelink) merged commit 8763b96 into mainMay 18, 2026
10 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the copilot/feature-generate-crash-report branch May 18, 2026 14:59
Amaury Levé (Evangelink) added a commit that referenced this pull request May 18, 2026
… follow-up) (#8328)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Generate crash report

4 participants

@Evangelink