unwinding icon indicating copy to clipboard operation
unwinding copied to clipboard

Build failure on aarch64 and riscv64 with recent nightlies

Open bjorn3 opened this issue 1 year ago • 13 comments

This is blocking https://github.com/sunfishcode/c-ward/pull/139.

$ rustc -vV
rustc 1.82.0-nightly (6de928dce 2024-08-18)
binary: rustc
commit-hash: 6de928dce9472b864f4e5d590dd7aa2075cb7551
commit-date: 2024-08-18
host: aarch64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0
$ CARGO_INCREMENTAL=0 cargo build --no-default-features --features "unwinder dwarf-expr fde-phdr-dl"
   Compiling unwinding v0.2.2 (/home/gh-bjorn3/c-ward/unwinding)
inlinable function call in a function with debug info must have a !dbg location
  call void @_Unwind_Resume(ptr %202) #16
rustc-LLVM ERROR: Broken module found, compilation aborted!
error: could not compile `unwinding` (lib)

bjorn3 avatar Aug 20 '24 19:08 bjorn3

The error message is from the LLVM IR verifier rule that "each inlinable callsite of a debug-info-bearing function in a debug-info-bearing function has a debug location attached to it". The compiler may be emitting a call to _Unwind_Resume without a debug location somewhere, which would normally work because _Unwind_Resume is normally not defined and thus not inlinable. In the unwinding crate though, _Unwind_Resume is defined, so it's inlinable, and it can have debug info, so the call with no debug info hits this rule.

A workaround is to add this to Cargo.toml:

[profile.dev]
debug = false

because then the function containing the callsite isn't debug-info-bearing and the rule doesn't apply.

sunfishcode avatar Aug 21 '24 00:08 sunfishcode

Unwinding marks _Unwind_Resume as #[inline(never)].

bjorn3 avatar Aug 21 '24 06:08 bjorn3

The code in LLVM doesn't check any inlining attributes.

My current theory is that the bug happens here where it creates a _Unwind_Resume call that doesn't seem to get a debug location. It's suspicious because a different _Unwind_Resume call here does have code to add a debug location, and even has a comment about how the verifier requires calls of debug-info-bearing functions from debug-info-bearing functions to have a debug location. However, I haven't yet confirmed that this is the problem.

sunfishcode avatar Aug 21 '24 09:08 sunfishcode

I guess I could check the IR to see where resume calls are generated, and try to tweak the code to not generate them... This will be fragile though

nbdd0121 avatar Aug 21 '24 10:08 nbdd0121

Another option would be to put the _Unwind_Resume definition in a separate crate which doesn't contain anything else, right? That would force it to be generated in a different codegen unit. You did still have LTO to worry about, but I don't think there is anything that can be done against that other than fixing LLVM as _Unwind_Resume calls will be coming from other crates than unwinding anyway.

bjorn3 avatar Aug 21 '24 12:08 bjorn3

Or defining _Unwind_Resume using inline asm, but rust currently doesn't have a way to then ensure the function gets exported from dylibs.

bjorn3 avatar Aug 21 '24 12:08 bjorn3

I've now confirmed my theory above, and posted https://github.com/llvm/llvm-project/pull/105513 to fix the bug in LLVM.

sunfishcode avatar Aug 21 '24 12:08 sunfishcode

BTW I tried to reproduce this on my x64 machine with rustc cross-compiling to aarch64 and riscv64 but can't reproduce it. Maybe Rustc's LLVM is compiled with different flags on x64/aarch64?

nbdd0121 avatar Aug 21 '24 12:08 nbdd0121

I can reproduce it on an x86_64 host in a clean unwinding checkout with the command CARGO_INCREMENTAL=0 cargo build --no-default-features --features "unwinder dwarf-expr fde-phdr-dl" --target=aarch64-unknown-linux-gnu.

sunfishcode avatar Aug 21 '24 12:08 sunfishcode

Ah I can produce it by downloading the prebuilt standard library, but not with -Zbuild-std, weird.

nbdd0121 avatar Aug 21 '24 12:08 nbdd0121

It looks like things work with a non-zero opt-level even with debug info enabled. @sunfishcode maybe you workaround on c-ward side by something like this while waiting for LLVM fix to be merged?

[profile.dev.package.unwinding]
opt-level = 1

nbdd0121 avatar Aug 21 '24 13:08 nbdd0121

The LLVM fix is now merged, and the backport to the release/19.x branch is now merged. It'll be some time before that's in a Rust builid, so thanks for the [profile.dev.package.unwinding] workaround idea, c-ward is now using until it's ready.

sunfishcode avatar Aug 26 '24 14:08 sunfishcode

The LLVM fix is now in LLVM 19.1.0-rc4.

sunfishcode avatar Sep 03 '24 23:09 sunfishcode

The LLVM fix is now in LLVM 19.1.0.

sunfishcode avatar Sep 18 '24 23:09 sunfishcode

The LLVM fix is now in the rust LLVM tree 19.1-2024-07-30 branch, which is now in Rust nightly, and c-ward's CI now passes with the workarounds removed. So I think we can consider this issue fixed.

sunfishcode avatar Oct 02 '24 17:10 sunfishcode

Thanks!

nbdd0121 avatar Oct 02 '24 18:10 nbdd0121