Set MSBUILDDEBUGPATH in build scripts for reliable crash diagnostics#126806
Set MSBUILDDEBUGPATH in build scripts for reliable crash diagnostics#126806danmoseley wants to merge 3 commits intodotnet:mainfrom
Conversation
…rash diagnostics The MSBUILDDEBUGPATH pipeline variable added in PR dotnet#126012 is not reaching the MSBuild process during Build product steps. Set the env var directly in the build scripts, matching the existing pattern in build-runtime.sh and tests/build.sh. Also create the directory with mkdir -p / New-Item -Force to avoid issues with MSBuild's EnsureDirectoryExists (which has no try/catch in its static constructor). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR ensures MSBuild crash diagnostics (e.g., MSBuild_*.failure.txt from MSB4166) are consistently written under artifacts/log/ by setting up and exporting MSBUILDDEBUGPATH directly in the top-level build scripts (eng/build.sh and eng/build.ps1), rather than relying solely on CI pipeline variables.
Changes:
- Set and export
MSBUILDDEBUGPATHineng/build.shand create the target directory before invoking MSBuild. - Set and export
MSBUILDDEBUGPATHineng/build.ps1, create the target directory, and update it per-configuration when building multiple configurations.
Show a summary per file
| File | Description |
|---|---|
| eng/build.sh | Adds MSBUILDDEBUGPATH initialization + mkdir -p so MSBuild crash logs land under artifacts/log/<Config>/MsbuildDebugLogs. |
| eng/build.ps1 | Adds MSBUILDDEBUGPATH initialization + directory creation, and updates the env var per configuration in multi-config builds. |
Copilot's findings
Comments suppressed due to low confidence (1)
eng/build.ps1:451
- Same as above: inside the per-configuration loop,
New-Itemerrors are non-terminating by default. If directory creation fails, the build continues and MSBuild crash diagnostics may not be captured underartifacts/log. Make directory creation terminating (e.g.,-ErrorAction Stop) to ensure reliability.
$msbuildDebugLogsDir = "$PSScriptRoot/../artifacts/log/$titleCaseConfig/MsbuildDebugLogs"
New-Item -ItemType Directory -Force -Path $msbuildDebugLogsDir | Out-Null
$env:MSBUILDDEBUGPATH = $msbuildDebugLogsDir
- Files reviewed: 2/2 changed files
- Comments generated: 2
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates top-level build entrypoints to ensure MSBuild crash diagnostics (MSBuild_*.failure.txt from MSB4166/node crashes) are consistently written under artifacts/log/ so CI reliably publishes them.
Changes:
- Set and export
MSBUILDDEBUGPATHearly ineng/build.sh, create the directory, and print it for diagnostics. - Set and export
MSBUILDDEBUGPATHearly ineng/build.ps1, create the directory, print it, and update it per configuration during multi-config builds.
Show a summary per file
| File | Description |
|---|---|
| eng/build.sh | Exports MSBUILDDEBUGPATH to a stable artifacts/log/<config>/MsbuildDebugLogs directory before invoking eng/common/build.sh. |
| eng/build.ps1 | Exports MSBUILDDEBUGPATH to artifacts/log/<config>/MsbuildDebugLogs, ensures the directory exists, and adjusts it when iterating configurations. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 1
| $titleCaseConfig = $((Get-Culture).TextInfo.ToTitleCase($config)) | ||
|
|
||
| # Update MSBuild debug logs directory for this configuration. | ||
| $msbuildDebugLogsDir = "$PSScriptRoot/../artifacts/log/$titleCaseConfig/MsbuildDebugLogs" | ||
| New-Item -ItemType Directory -Force -Path $msbuildDebugLogsDir | Out-Null | ||
| $env:MSBUILDDEBUGPATH = $msbuildDebugLogsDir | ||
| Write-Host "MSBUILDDEBUGPATH=$msbuildDebugLogsDir" |
There was a problem hiding this comment.
In the multi-configuration loop you update $env:MSBUILDDEBUGPATH per config, but MSBuild node reuse is enabled by default for non-CI runs (/nr:true via eng/common/tools.ps1 where nodeReuse defaults to !$ci). Reused nodes won’t see the updated environment variable, so crash diagnostics may still be written to the previous configuration’s directory, making the per-config directory update potentially misleading. Consider either keeping a single MSBUILDDEBUGPATH for the whole build.ps1 invocation, or disabling node reuse when switching configurations so each config reliably writes to its intended directory.
See below for a potential fix:
# Use a single MSBuild debug logs directory for the entire invocation because
# reused MSBuild nodes do not observe environment variable updates made between
# configurations.
$msbuildDebugLogsDir = "$PSScriptRoot/../artifacts/log/MsbuildDebugLogs"
New-Item -ItemType Directory -Force -Path $msbuildDebugLogsDir | Out-Null
$env:MSBUILDDEBUGPATH = $msbuildDebugLogsDir
Write-Host "MSBUILDDEBUGPATH=$msbuildDebugLogsDir"
foreach ($config in $configuration) {
$titleCaseConfig = $((Get-Culture).TextInfo.ToTitleCase($config))
Set MSBUILDDEBUGPATH directly in eng/build.sh for reliable crash diagnostics
PR #126012 added
MSBUILDDEBUGPATHas an AzDO pipeline variable inglobal-build-job.ymlso that MSBuild crash diagnostics (MSBuild_*.failure.txt) would be written toartifacts/log/instead of the system temp directory. However, recent builds that hit the MSB4166 crash (e.g., build 1370423) still show MSBuild writing to the default temp path, indicating the pipeline variable is not reaching the MSBuild process.Other build scripts (
src/coreclr/build-runtime.sh,src/tests/build.sh) already set and exportMSBUILDDEBUGPATHindependently, which is why "Build Tests" steps work. The "Build product" step callseng/build.sh, which did not set it.This PR sets
MSBUILDDEBUGPATHdirectly ineng/build.shandeng/build.ps1before anycommon/build.sh/common/build.ps1invocations, matching the pattern used by the other scripts. This also:mkdir -pbefore MSBuild starts (MSBuild'sEnsureDirectoryExistshas no try/catch in its static constructor, so a failed directory creation would silently fall back to the temp dir)The existing pipeline variable in
global-build-job.ymlis left in place as defense-in-depth.Relates to getting data to fix #92290