Skip to content

Panic unwinding fails on macOS targets when using the Xcode 15 beta #113783

@ptxmac

Description

@ptxmac

Platform:

  • macOS Sonoma 14.0 Beta (23A5286i)
  • Apple Silicon
  • Xcode 15 beta 4

I tried this code:

use std::panic;

fn main() {
    _ = panic::catch_unwind(|| {
        assert!(false, "should be recoverable");
    });
    println!("--- Normal assert is caught");

    _ = panic::catch_unwind(|| {
        assert_eq!(1, 2, "should also be recoverable");
    });
    println!("--- assert_eq crashes the runtime!");
}

I expected to see this happen:

Both println! statements should be printed

Instead, this happened:

The first part of the code completed correctly, but the assert_eq does not:

thread 'main' panicked at 'should be recoverable', src/main.rs:14:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
--- Normal assert is caught
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `2`: should also be recoverable', src/main.rs:19:9
fatal runtime error: failed to initiate panic, error 5

A quick exploration with a debugger showed that the runtime was aborted from std/paniking.rs:

/// An unmangled function (through `rustc_std_internal_symbol`) on which to slap
/// yer breakpoints.
#[inline(never)]
#[cfg_attr(not(test), rustc_std_internal_symbol)]
fn rust_panic(msg: &mut dyn BoxMeUp) -> ! {
    let code = unsafe { __rust_start_panic(msg) };
    rtabort!("failed to initiate panic, error {code}")
}

So the call to __rust_start_panic failed to unwind

Conclusion

My guess is that something have changed in libSystem that breaks stack unwinding. But is'a strange that it only happens for the assert_eq/assert_ne macros, but panic/assert works as expected

Fix

Installing Xcode 14 and setting it as the active toolchain using xcode-select mitigates the problem.
Xcode 14 won't open on macOS 15, but the command line tools works perfectly

Meta

Tested on both stable (1.71) and nightly (2023-07-16)

rustc --version --verbose:

rustc 1.73.0-nightly (0e8e857b1 2023-07-16)
binary: rustc
commit-hash: 0e8e857b11f60a785aea24a84f280f6dad7a4d42
commit-date: 2023-07-16
host: aarch64-apple-darwin
release: 1.73.0-nightly
LLVM version: 16.0.5
rustc 1.71.0 (8ede3aae2 2023-07-12)
binary: rustc
commit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225
commit-date: 2023-07-12
host: aarch64-apple-darwin
release: 1.71.0
LLVM version: 16.0.5
Backtrace

thread 'main' panicked at 'should be recoverable', src/main.rs:14:9
stack backtrace:
   0: std::panicking::begin_panic
   1: main::main::{{closure}}
   2: std::panicking::try::do_call
   3: ___rust_try
   4: std::panicking::try
   5: std::panic::catch_unwind
   6: main::main
   7: core::ops::function::FnOnce::call_once
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
--- Normal assert is caught
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `1`,
 right: `2`: should also be recoverable', src/main.rs:19:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/8ede3aae28fe6e4d52b38157d7bfe0d3bceef225/library/core/src/panicking.rs:67:14
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
fatal runtime error: failed to initiate panic, error 5```

</p>
</details>

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-macosOperating system: macOSP-criticalCritical priority

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions