Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
ptxmac opened this issue Jul 17, 2023 · 32 comments
Closed

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

ptxmac opened this issue Jul 17, 2023 · 32 comments
Labels
C-bug Category: This is a bug. O-macos Operating system: macOS P-critical Critical priority

Comments

@ptxmac
Copy link

ptxmac commented Jul 17, 2023

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>
@ptxmac ptxmac added the C-bug Category: This is a bug. label Jul 17, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 17, 2023
@coolbluewater
Copy link

I'm seeing the same issue with Xcode 15 beta 4. (I think the OP meant to say 'Xcode 15' in the first line, not Xcode 14).

Reverting the version of the Xcode Command Line Tools via Xcode/Settings/Locations to the Xcode 14 toolchain fixes the problem for me. I remember reading somewhere that Xcode 15 has some breaking changes to clang that affect Rust.

@ptxmac
Copy link
Author

ptxmac commented Jul 17, 2023

I'm seeing the same issue with Xcode 15 beta 4. (I think the OP meant to say 'Xcode 15' in the first line, not Xcode 14).

In the first line I mention that reverting to Xcode 14 is a fix - I'll rewrite it to make it more clear

@davidtwco davidtwco added the O-macos Operating system: macOS label Jul 18, 2023
@davidtwco
Copy link
Member

For anyone stumbling upon this, to revert to Xcode 14:

  1. Download the full Xcode 14 application from Apple.
    • You would normally only download the command line tools, but the installer won't let you perform the installation on macOS Sonoma, so download the entire application.
  2. Unarchive the .xip archive.
  3. Copy Xcode.app into /Applications.
  4. Run sudo xcode-select -s /Applications/Xcode.app/ to switch back to the Xcode 14 command line tools.
    • You won't actually be able to run Xcode.app, but that's not necessary to use the command line tools.
    • Similarly, you won't be able to select the Xcode 14 command line tools in the Xcode 15 beta application - I had to use xcode-select to do so.

@ptxmac
Copy link
Author

ptxmac commented Jul 18, 2023

Additionally, https://www.xcodes.app is a great app for managing multiple versions of Xcode!

@dustinlieu
Copy link

dustinlieu commented Jul 21, 2023

I encountered this issue when using #[should_panic] in a test.

#[cfg(test)]
mod tests {
    #[test]
    #[should_panic]
    fn it_works() {
        panic!("panicking");
    }
}
$ cargo test
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/dummy-41bdf4d3138a58ed)

running 1 test
fatal runtime error: failed to initiate panic, error 3
error: test failed, to rerun pass `--lib`

Caused by:
  process didn't exit successfully: `/Users/person/dummy/target/debug/deps/dummy-41bdf4d3138a58ed` (signal: 6, SIGABRT: process abort signal)

I tried the workaround by @davidtwco's instructions but that did not work.
Works now with Xcode 14 after a cargo clean.

@thomcc
Copy link
Member

thomcc commented Jul 21, 2023

No idea what the deal here is (and it will be a couple weeks until I can debug this), but this will be a significant problem when XCode 15 releases1, since it will mean a tier-1 platform doesn't have a working panic=unwind runtime.

Note that the actual MVCE is just fn main() { panic!(); }.

Footnotes

  1. which technically nobody knows when will happen, but there's reason to believe will be in about 2 months, since it usually is just before the iOS release, and often is mid-September.

@thomcc thomcc changed the title assert_eq failes when using Xcode 15 beta 4 on macOS 14 beta Panic unwinding fails on Xcode 15 beta Jul 22, 2023
@thomcc thomcc changed the title Panic unwinding fails on Xcode 15 beta Panic unwinding fails on macOS targets when using the Xcode 15 beta Jul 22, 2023
@thomcc thomcc added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Jul 22, 2023
@thomcc
Copy link
Member

thomcc commented Jul 22, 2023

I don't really have the time to look into this now in depth but I took a peek. Error code 3 is _URC_FATAL_PHASE1_ERROR, which doesn't mean a whole lot to me, but I did find out that it looks like we might be able to get some more info if LIBUNWIND_PRINT_UNWINDING=1 is set in the environment.

@thomcc
Copy link
Member

thomcc commented Jul 22, 2023

This fails due to libunwind: _Unwind_GetTextRelBase - _Unwind_GetTextRelBase() not implemented.

@apiraino
Copy link
Contributor

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-critical +E-needs-bisection

@rustbot rustbot added E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc P-critical Critical priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Jul 24, 2023
@apiraino
Copy link
Contributor

apiraino commented Jul 24, 2023

@rustbot ping macos

any chance to bisect the mcve mentioned in this comment?

@rustbot
Copy link
Collaborator

rustbot commented Jul 24, 2023

Error: Parsing ping command in comment failed: ...'ping macos' | error: expected end of command at >| ', any chan'...

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.

@rustbot
Copy link
Collaborator

rustbot commented Jul 24, 2023

Hey MacOS Group! This issue or PR could use some MacOS-specific guidance. Could one
of you weigh in? Thanks <3

cc @hkratz @inflation @nvzqz @shepmaster @thomcc

@ehuss
Copy link
Contributor

ehuss commented Jul 24, 2023

@apiraino I don't think this is something that needs a bisection because I don't think it is a regression in rustc. It's a regression in Xcode 15.

@inflation
Copy link

I suspect it's because of the new linker. Any luck with lld or mold?

@apiraino
Copy link
Contributor

I don't think this is something that needs a bisection because I don't think it is a regression in rustc. It's a regression in Xcode 15.

if this an issue with Xcode, are you therefore implying that Apple will fix that? I could not find evidence of that yet (though I didn't search deeply). My thinking was if we should investigate if this is connected to the unwind library ~recently introduced in rustc and find a quick solution before the next Xcode release1.

Footnotes

  1. even if it's not strictly rustc's fault I can imagine where bugs will be opened when/if macOS users can't unwind their panics!()

@thomcc
Copy link
Member

thomcc commented Jul 24, 2023

I suspect it's because of the new linker. Any luck with lld or mold?

Yes, lld does seem to fix it. I've filed a bug upstream about this (FB12734052 in case anybody looking has the ability to do anything about that), since it's looking increasingly likely that it's not our bug.

@ehuss
Copy link
Contributor

ehuss commented Jul 24, 2023

if this an issue with Xcode, are you therefore implying that Apple will fix that?

I'm not sure what the options are. This isn't due to a change in the rustc side since at least 1.54 (about two years ago). From what I can tell, this was introduced in Xcode 15 beta 3 (beta 2 seems to work). Strangely, the full Xcode beta 3 seems to have been removed from the downloads page, so I could only test the command-line tools for that release, but the full beta 4 also fails. It may be possible we could make a change to work around the issue, but I don't know.

@ptxmac
Copy link
Author

ptxmac commented Jul 25, 2023

Just a heads up, Xcode 15 beta 5 was just released and the issue is still present

@Noratrieb Noratrieb removed E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jul 29, 2023
@thomcc
Copy link
Member

thomcc commented Jul 30, 2023

Worth noting that with ld-classic (which seems to be their pre-rewrite version of the linker), this issue is not present. E.g. RUSTFLAGS="-Clink-arg=-fuse-ld=/Applications/Xcode-15.0.0-Beta.5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld-classic" works fine, which seems to confirm its an issue with their new linker, and not something else.

@ptxmac
Copy link
Author

ptxmac commented Aug 9, 2023

Good news! This seems to have been fixed in Xcode 15 beta 6

@thomcc
Copy link
Member

thomcc commented Aug 11, 2023

Yep! It seems that poking the developer sometimes works!

Going to close this for now since it seems completely resolved. Hopefully that's not premature.

@thomcc thomcc closed this as completed Aug 11, 2023
@guswynn
Copy link
Contributor

guswynn commented Sep 26, 2023

This continues to be a problem with the non-beta release of Xcode15

I can work around it using this in my ~/.cargo/config, but apple seems adamant here: https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes that this linker is going to go away? Is this something can be escalated?

[target."aarch64-apple-darwin"]
# linker = "/usr/bin/clang"
# Xcode15-
rustflags=["-Clink-arg=-fuse-ld=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld-classic"]

@thomcc
Copy link
Member

thomcc commented Sep 26, 2023

I just checked and I can't reproduce on the non-beta Xcode 15. If you can give me steps to reproduce I can bug someone about it.

@guswynn
Copy link
Contributor

guswynn commented Sep 26, 2023

@thomcc I believe trying to build this crate https://github.com/MaterializeInc/materialize/tree/main/src/sqllogictest with RUST_BACKTRACE=0 will trigger it (at least on my m1 mac it does)

@thomcc
Copy link
Member

thomcc commented Sep 28, 2023

I, uh, don't suppose you've seen it in anything less massive, have you?

@thomcc
Copy link
Member

thomcc commented Sep 28, 2023

I also can't reproduce. Or don't know if I can. Certainly RUST_BACKTRACE=0 cargo test from within that directory passes (as do other values of RUST_BACKTRACE).

@guswynn
Copy link
Contributor

guswynn commented Oct 2, 2023

@thomcc Ill try to find time to reduce it! for now using ld-classic is working

@thomcc
Copy link
Member

thomcc commented Oct 4, 2023

Even non-reduced I can't reproduce the issue you're describing.

@guswynn
Copy link
Contributor

guswynn commented Oct 4, 2023

@thomcc I can't anymore either...this was fairly consistent last week; if I hit it again ill try to collect more info...

@thomcc
Copy link
Member

thomcc commented Oct 5, 2023

Is it possible you had some artifacts still built with the older SDK?

@guswynn
Copy link
Contributor

guswynn commented Oct 5, 2023

@thomcc I fairly regularly clean my target/ dir but its totally possible! sorry for the noise!

@thomcc
Copy link
Member

thomcc commented Oct 11, 2023

This (well, a related issue that produces the same error) does seem to happen on some projects. It's fixed in the XCode 15.1 beta though.

(Also, FYI, -Clink-arg=-Wl,-ld_classic is a way to force use of ld-classic without having to hardcode the path)

scsmithr added a commit to GlareDB/glaredb that referenced this issue Oct 27, 2023
I was having some issues with panics not showing backtraces, and instead showing
the following:

```
libunwind: stepWithCompactEncoding - invalid compact unwind encoding
```

This seems to be from the latest mac update using a new linker. See rust-lang/rust#113783

As an aside, I think might have an errant panic somewhere that's not getting
bubbled up properly.
ramnivas added a commit to exograph/exograph that referenced this issue Feb 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-macos Operating system: macOS P-critical Critical priority
Projects
None yet
Development

No branches or pull requests