Open bjorn3 opened 3 weeks ago
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.
Unwinding marks _Unwind_Resume
as #[inline(never)]
.
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.
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
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.
Or defining _Unwind_Resume
using inline asm, but rust currently doesn't have a way to then ensure the function gets exported from dylibs.
I've now confirmed my theory above, and posted https://github.com/llvm/llvm-project/pull/105513 to fix the bug in LLVM.
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?
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
.
Ah I can produce it by downloading the prebuilt standard library, but not with -Zbuild-std
, weird.
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
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.
The LLVM fix is now in LLVM 19.1.0-rc4.
This is blocking https://github.com/sunfishcode/c-ward/pull/139.