aarch64-pc-windows-msvc: safe Rust exits with 0xC0000409 after a caught panic at opt-level=1

Open
#165,346 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
12/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
rust

Research direction

Start by building the reduced main.rs from the issue with -C opt-level=1 -C target-feature=+crt-static on aarch64-pc-windows-msvc and confirm the exit code is 0xC0000409. The likely area is how the panic unwinds through the Mutex guard and catch_unwind at that optimization level, so look at the codegen or unwinding path for those constructs. Done means the reproducer exits successfully at level 1 and the fix is covered by a regression test.

Written by the indexing model from the issue text.

Description

A-LLVM A-target-feature I-miscompile I-prioritize O-aarch64-pc-windows-msvc regression-from-stable-to-stable T-compiler

A safe Rust program on aarch64-pc-windows-msvc catches a panic, prints its last line, then exits with 0xC0000409 at optimization level 1.

I found this while reducing a RustGIS renderer test (original report). This reduced program uses only the standard library:

#![forbid(unsafe_code)]

use std::sync::Mutex;
#[derive(Default)]
struct Cache(Mutex<Option<f32>>);
impl Cache {
    fn measure(&self, uncached: impl FnOnce() -> f32) -> f32 {
        if let Some(width) = *self.0.lock().unwrap() { return width; }
        let width = uncached();
        *self.0.lock().unwrap() = Some(width);
        width
    }
}
fn main() {
    let cache = Cache::default();
    let failed = std::panic::catch_unwind(|| cache.measure(|| panic!("measurement failed")));
    assert!(failed.is_err());
    println!("real ok");
}

Compile and run on Windows ARM64:

rustc +1.99.1 --crate-name repro --edition 2024 -C opt-level=1 -C target-feature=+crt-static -C debuginfo=1 main.rs -o repro.exe
.\repro.exe
$LASTEXITCODE

I expected the panic to be caught and the program to exit successfully. The panic hook's message on stderr is expected.

Instead, it prints real ok, then the process exits with -1073740791 (0xC0000409). Removing the cache and catching the panic directly exits successfully. A version that only locks and unlocks a Mutex<()> before calling the panicking callback also exits successfully.

The reduced program and controls were run on GitHub's windows-11-arm runner. Diagnostic run and source artifacts. Each toolchain artifact's 12-mutex-option folder contains this source and its executables. Artifacts expire after seven days; the source above is complete.

The original and reduced programs both exit with 0xC0000409 at opt-level=1, and exit successfully at levels 0, 2, and 3, on all three tested toolchains: stable 1.99.1, beta 1.100.0-beta.7, and nightly 1.101.0-nightly (2026-11-01). Both controls described above exit successfully at level 1 on all three. The failing runs print real ok before exiting.

The diagnostic workflow records process exit codes without failing its job, so its green status does not mean the reproducer passed.

Meta
rustc 1.99.1 (58cf8f9c3 2026-10-13)
binary: rustc
commit-hash: 58cf8f9c35b355199727627d07ae34a4e2846d67
commit-date: 2026-10-13
host: aarch64-pc-windows-msvc
release: 1.99.1
LLVM version: 23.1.1

Beta:

rustc 1.100.0-beta.7 (fd8e211ae 2026-10-17)
binary: rustc
commit-hash: fd8e211ae301c84a86d13cf52a6d3ce08c589e2e
commit-date: 2026-10-17
host: aarch64-pc-windows-msvc
release: 1.100.0-beta.7
LLVM version: 23.1.4

Nightly:

rustc 1.101.0-nightly (3e92e1a2d 2026-11-01)
binary: rustc
commit-hash: 3e92e1a2d20b991ef23a6c6064c34d57ee8c98d3
commit-date: 2026-11-01
host: aarch64-pc-windows-msvc
release: 1.101.0-nightly
LLVM version: 23.1.5
Dominant language
Rust
Stars
121k
Forks
17.3k
Avg merge
2d 21h
Merged PRs (30d)
531

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from rust-lang/rust

All issues in rust-lang/rust

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.