Skip to content

[ci] Set __PWSH_LOGIN_CHECKED to avoid macOS pwsh 'procargs failed' startup crashes - #35724

Merged
PureWeen merged 1 commit into
mainfrom
pureween/pwsh-procargs-workaround-main
Jun 3, 2026
Merged

[ci] Set __PWSH_LOGIN_CHECKED to avoid macOS pwsh 'procargs failed' startup crashes#35724
PureWeen merged 1 commit into
mainfrom
pureween/pwsh-procargs-workaround-main

Conversation

@PureWeen

@PureWeen PureWeen commented Jun 3, 2026

Copy link
Copy Markdown
Member

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!

Description

PowerShell 7.4.x intermittently crashes at startup on macOS with:

Call to 'procargs' failed with errno 5
Unhandled exception. Microsoft.PowerShell.ManagedPSEntry+StartupException
   at Microsoft.PowerShell.ManagedPSEntry.ThrowOnFailure(String call, Int32 code)
   at Microsoft.PowerShell.ManagedPSEntry.AttemptExecPwshLogin(String[] args)
   at Microsoft.PowerShell.ManagedPSEntry.Main(String[] args)

This is PowerShell/PowerShell#20802 — open and untriaged since November 2023, 0 comments, no linked PRs, no fix shipped. The crash happens in AttemptExecPwshLogin, which on macOS calls sysctl(KERN_PROCARGS2) to inspect its own argv[0] and decide whether pwsh was launched as a login shell. That sysctl call races intermittently and returns errno 5, aborting startup before pwsh reads any user script.

Repro / impact

Hit on the internal dotnet-maui pipeline (definition 1095), build 2990586, during release-prep for release/11.0.1xx-preview5:

##[section]Starting: Provision Android SDK - Common PackagesCall to 'procargs' failed with errno 5 → task fails with exit code null.

A rerun on a different agent passed, but every macOS pwsh: / PowerShell@2 step in the pipeline is a flake risk going forward. Inventory: ~57 pwsh tasks across 15 pipeline YAMLs, ~45 of them on macOS-eligible jobs.

Fix

PowerShell itself ships a short-circuit for this code path. From src/powershell/Program.cs:

private const string LOGIN_ENV_VAR_NAME = "__PWSH_LOGIN_CHECKED";

if (Environment.GetEnvironmentVariable(LOGIN_ENV_VAR_NAME) != null)
{
    Environment.SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null);
    return;   // ← skips the racy sysctl(KERN_PROCARGS2) entirely
}

Setting __PWSH_LOGIN_CHECKED=1 makes pwsh skip the racy syscall. This PR declares it as a pipeline-level variable in eng/pipelines/common/variables.yml (included by every macOS-touching pipeline — ci.yml, ci-official.yml, ci-device-tests.yml, ci-copilot.yml, ci-uitests.yml, device-tests.yml, ui-tests.yml, handlers.yml, etc.). Per AzDO docs, user-defined variables are injected as environment variables for every task — so every pwsh: / PowerShell@2 step in every job inherits it.

Safety analysis

This is safe because:

  • CI never wants login-shell semantics. No -Login flag, no leading - in argv[0]. The skipped code's IsLogin() check would have returned false and the function would have returned without doing anything visible. We just avoid the broken syscall that precedes that decision.
  • The env var is single-use per process. AttemptExecPwshLogin consumes it via SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null), so nested pwsh-launches-pwsh scenarios still work normally (each new task gets a fresh AzDO-injected value).
  • Windows is unaffected. The read is inside a #if UNIX block; Windows pwsh ignores the var entirely. Setting it on Windows agents is a no-op.
  • Safe even under -Login. If a future step explicitly adds -Login, the short-circuit still routes around the broken syscall — the same syscall the login-shell detection relies on. So there's no regression even in that (currently nonexistent) use case.

Empirical validation

Verified locally on pwsh 7.4.5 / macOS 26.5 (same 7.4.x minor as the CI agent that crashed):

Run Command Result
Control pwsh ... -Command 'Write-Output "envvar=[$Env:__PWSH_LOGIN_CHECKED]"' envvar=[] (var unset; nothing to clear)
Test __PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'Write-Output "envvar=[$Env:__PWSH_LOGIN_CHECKED]"' envvar=[]proves the short-circuit ran (the only line that clears the var is inside the skip-path; if it cleared, the racy syscall was never reached)
Soak 100 × __PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'exit 0' 0/100 failures; no behavioral change

Backport plan

  • This PR: main (.NET 10 SR dev). Drives the fix into ongoing servicing builds.
  • Will cherry-pick to net11.0 afterward (where build 2990586 crashed during preview5 prep). Diff is verified to apply cleanly to both branches.

Related macOS-agent flakes (out of scope)

The same dnceng macOS agent pool has produced other, unrelated flakes during this release-prep window (e.g. IDEDownloadableMetalToolchainCoordinator: Failed to remount and iOS 26.2 platform not installed on builds 2990581 and 2990384). Those are agent-image issues and need agent-side fixes — they're not addressed here. This PR fixes one specific class of macOS flake (pwsh startup race), not all of them.

…tartup crashes

PowerShell 7.4.x intermittently aborts at startup on macOS with:

  Call to 'procargs' failed with errno 5
  Unhandled exception. Microsoft.PowerShell.ManagedPSEntry+StartupException
     at Microsoft.PowerShell.ManagedPSEntry.ThrowOnFailure(String call, Int32 code)
     at Microsoft.PowerShell.ManagedPSEntry.AttemptExecPwshLogin(String[] args)
     at Microsoft.PowerShell.ManagedPSEntry.Main(String[] args)

This is PowerShell/PowerShell#20802, open and untriaged since Nov 2023.
AttemptExecPwshLogin uses sysctl(KERN_PROCARGS2) to detect login-shell
mode; that syscall races on macOS and intermittently returns errno 5,
aborting startup before pwsh reads any user script.

PowerShell itself ships a short-circuit env var __PWSH_LOGIN_CHECKED;
when set, AttemptExecPwshLogin returns immediately and never reaches
the racy syscall. Setting it pipeline-wide in common/variables.yml
(included by every macOS-touching pipeline) eliminates the flake with
zero behavior change in CI (we never want login-shell semantics there).

Hit on internal dnceng dotnet-maui build 2990586
(release/11.0.1xx-preview5).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35724

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35724"
@github-actions github-actions Bot added the area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions label Jun 3, 2026
@PureWeen
PureWeen merged commit 1221e4d into main Jun 3, 2026
36 checks passed
@PureWeen
PureWeen deleted the pureween/pwsh-procargs-workaround-main branch June 3, 2026 17:20
@github-actions github-actions Bot added this to the .NET 10.0 SR8 milestone Jun 3, 2026
Dhivya-SF4094 pushed a commit to Dhivya-SF4094/maui that referenced this pull request Jun 15, 2026
…tartup crashes (dotnet#35724)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

## Description

PowerShell 7.4.x intermittently crashes at startup on macOS with:

```
Call to 'procargs' failed with errno 5
Unhandled exception. Microsoft.PowerShell.ManagedPSEntry+StartupException
   at Microsoft.PowerShell.ManagedPSEntry.ThrowOnFailure(String call, Int32 code)
   at Microsoft.PowerShell.ManagedPSEntry.AttemptExecPwshLogin(String[] args)
   at Microsoft.PowerShell.ManagedPSEntry.Main(String[] args)
```

This is
[PowerShell/PowerShell#20802](PowerShell/PowerShell#20802)
— open and untriaged since November 2023, **0 comments, no linked PRs,
no fix shipped**. The crash happens in `AttemptExecPwshLogin`, which on
macOS calls `sysctl(KERN_PROCARGS2)` to inspect its own `argv[0]` and
decide whether pwsh was launched as a login shell. That `sysctl` call
races intermittently and returns `errno 5`, aborting startup before pwsh
reads any user script.

## Repro / impact

Hit on the internal `dotnet-maui` pipeline (definition 1095), build
**2990586**, during release-prep for `release/11.0.1xx-preview5`:

> `##[section]Starting: Provision Android SDK - Common Packages` → `Call
to 'procargs' failed with errno 5` → task fails with exit code `null`.

A rerun on a different agent passed, but every macOS `pwsh:` /
`PowerShell@2` step in the pipeline is a flake risk going forward.
Inventory: ~57 pwsh tasks across 15 pipeline YAMLs, ~45 of them on
macOS-eligible jobs.

## Fix

PowerShell itself ships a short-circuit for this code path. From
[`src/powershell/Program.cs`](https://github.com/PowerShell/PowerShell/blob/master/src/powershell/Program.cs):

```csharp
private const string LOGIN_ENV_VAR_NAME = "__PWSH_LOGIN_CHECKED";

if (Environment.GetEnvironmentVariable(LOGIN_ENV_VAR_NAME) != null)
{
    Environment.SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null);
    return;   // ← skips the racy sysctl(KERN_PROCARGS2) entirely
}
```

Setting `__PWSH_LOGIN_CHECKED=1` makes pwsh skip the racy syscall. This
PR declares it as a pipeline-level variable in
`eng/pipelines/common/variables.yml` (included by every macOS-touching
pipeline — `ci.yml`, `ci-official.yml`, `ci-device-tests.yml`,
`ci-copilot.yml`, `ci-uitests.yml`, `device-tests.yml`, `ui-tests.yml`,
`handlers.yml`, etc.). Per [AzDO
docs](https://learn.microsoft.com/azure/devops/pipelines/process/variables),
user-defined variables are injected as environment variables for every
task — so every `pwsh:` / `PowerShell@2` step in every job inherits it.

## Safety analysis

This is safe because:

- **CI never wants login-shell semantics.** No `-Login` flag, no leading
`-` in `argv[0]`. The skipped code's `IsLogin()` check would have
returned `false` and the function would have returned without doing
anything visible. We just avoid the broken syscall that precedes that
decision.
- **The env var is single-use per process.** `AttemptExecPwshLogin`
consumes it via `SetEnvironmentVariable(LOGIN_ENV_VAR_NAME, null)`, so
nested `pwsh-launches-pwsh` scenarios still work normally (each new task
gets a fresh AzDO-injected value).
- **Windows is unaffected.** The read is inside a `#if UNIX` block;
Windows pwsh ignores the var entirely. Setting it on Windows agents is a
no-op.
- **Safe even under `-Login`.** If a future step explicitly adds
`-Login`, the short-circuit still routes around the broken syscall — the
same syscall the login-shell *detection* relies on. So there's no
regression even in that (currently nonexistent) use case.

## Empirical validation

Verified locally on `pwsh 7.4.5` / macOS 26.5 (same 7.4.x minor as the
CI agent that crashed):

| Run | Command | Result |
| --- | --- | --- |
| Control | `pwsh ... -Command 'Write-Output
"envvar=[$Env:__PWSH_LOGIN_CHECKED]"'` | `envvar=[]` (var unset; nothing
to clear) |
| Test | `__PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'Write-Output
"envvar=[$Env:__PWSH_LOGIN_CHECKED]"'` | `envvar=[]` ← **proves the
short-circuit ran** (the only line that clears the var is inside the
skip-path; if it cleared, the racy syscall was never reached) |
| Soak | 100 × `__PWSH_LOGIN_CHECKED=1 pwsh ... -Command 'exit 0'` |
**0/100 failures**; no behavioral change |

## Backport plan

- This PR: `main` (.NET 10 SR dev). Drives the fix into ongoing
servicing builds.
- Will cherry-pick to `net11.0` afterward (where build 2990586 crashed
during preview5 prep). Diff is verified to apply cleanly to both
branches.

## Related macOS-agent flakes (out of scope)

The same dnceng macOS agent pool has produced other, *unrelated* flakes
during this release-prep window (e.g.
`IDEDownloadableMetalToolchainCoordinator: Failed to remount` and `iOS
26.2 platform not installed` on builds 2990581 and 2990384). Those are
agent-image issues and need agent-side fixes — they're not addressed
here. This PR fixes one specific class of macOS flake (pwsh startup
race), not all of them.

Co-authored-by: bot <bot@test>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-infrastructure CI, Maestro / Coherency, upstream dependencies/versions

2 participants