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

non-pub function no longer compiled in debug profile, causing link errors on thumbv7em-none-eabihf with defmt #131164

Closed
jonathanpallant opened this issue Oct 2, 2024 · 30 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Milestone

Comments

@jonathanpallant
Copy link
Contributor

Code

I tried this code:

$ git clone https://github.com/ferrous-systems/rust-exercises.git
$ cd rust-exercises
$ git checkout v1.17.0
$ cd nrf52_code/radio_app
$ rustup target add thumbv7em-none-eabihf --toolchain=nightly
$ cargo install flip-link (or change `.cargo/config.toml` to not use flip-link - either is fine)
$ cargo +nightly build

I expected to see this happen:

The binaries build like, they do on stable.

Instead, this happened:

  = note: rust-lld: error: /Users/jonathan/Documents/clients/training/open-rust-embedded-2024-10-02/rust-exercises-v1.17.0/nrf52-code/radio-app/target/thumbv7em-none-eabihf/debug/build/defmt-36a2ab5d209daca3/out/defmt.x:7: symbol not found: __defmt_default_panic
          rust-lld: error: /Users/jonathan/Documents/clients/training/open-rust-embedded-2024-10-02/rust-exercises-v1.17.0/nrf52-code/radio-app/target/thumbv7em-none-eabihf/debug/build/defmt-36a2ab5d209daca3/out/defmt.x:7: symbol not found: __defmt_default_panic
          rust-lld: error: /Users/jonathan/Documents/clients/training/open-rust-embedded-2024-10-02/rust-exercises-v1.17.0/nrf52-code/radio-app/target/thumbv7em-none-eabihf/debug/build/defmt-36a2ab5d209daca3/out/defmt.x:7: symbol not found: __defmt_default_panic
          rust-lld: error: /Users/jonathan/Documents/clients/training/open-rust-embedded-2024-10-02/rust-exercises-v1.17.0/nrf52-code/radio-app/target/thumbv7em-none-eabihf/debug/build/defmt-36a2ab5d209daca3/out/defmt.x:7: symbol not found: __defmt_default_panic

That symbol is defined here: https://github.com/knurling-rs/defmt/blob/b7a89f56059fc66ac3c7cc3445d092829599e699/defmt/src/lib.rs#L365

Bisect

@Dirbaio said:

searched nightlies: from nightly-2024-07-30 to nightly-2024-10-02
regressed nightly: nightly-2024-08-01
searched commit range: f8060d2...28a58f2
regressed commit: 0b5eb7b

That's the LLVM 19 upgrade.

@jonathanpallant jonathanpallant added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Oct 2, 2024
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 2, 2024
@Dirbaio
Copy link
Contributor

Dirbaio commented Oct 2, 2024

it regressed both with and without --release.

@jonathanpallant
Copy link
Contributor Author

I also ran a bisect:

searched nightlies: from nightly-2024-07-01 to nightly-2024-10-02
regressed nightly: nightly-2024-08-01
searched commit range: f8060d2...28a58f2
regressed commit: 0b5eb7b

@saethlin saethlin added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Oct 2, 2024
@apiraino
Copy link
Contributor

apiraino commented Oct 2, 2024

WG-prioritization assigning priority (Zulip discussion).

I can also reproduce on current beta so tagging accordingly

@rustbot label -I-prioritize +P-medium +regression-from-stable-to-beta

@rustbot rustbot added P-medium Medium priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 2, 2024
@nikic nikic added the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Oct 2, 2024
@Dirbaio
Copy link
Contributor

Dirbaio commented Oct 2, 2024

minimized, zero deps -> https://github.com/Dirbaio/defmt-repro

[dirbaio@mars defmt-repro]$ rustc --version
rustc 1.83.0-nightly (06bb8364a 2024-10-01)
[dirbaio@mars defmt-repro]$ cargo build
   Compiling radio_app v0.0.0 (/home/dirbaio/defmt-repro)
error: linking with `rust-lld` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/home/dirb(snip)47a" "--gc-sections" "-Tlol.x"
  = note: rust-lld: error: lol.x:1: symbol not found: __defmt_default_panic
          rust-lld: error: lol.x:1: symbol not found: __defmt_default_panic
          rust-lld: error: lol.x:1: symbol not found: __defmt_default_panic

error: could not compile `radio_app` (bin "radio_app") due to 1 previous error
[dirbaio@mars defmt-repro]$ rustc +stable --version
rustc 1.81.0 (eeb90cda1 2024-09-04)
[dirbaio@mars defmt-repro]$ cargo +stable build
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s

@Dirbaio
Copy link
Contributor

Dirbaio commented Oct 2, 2024

maybe related: llvm/llvm-project@ebb326a

@jannic
Copy link
Contributor

jannic commented Oct 3, 2024

It seems to all depend on the linker version, not the compiler itself. Using ldd from beta/nightly with a stable compiler triggers this issue. Using ldd from stable on a beta/nightly compiler doesn't.

So I compiled lld from llvm myself, and can confirm: With lld built from commit ebb326a51fec37b5a47e5702e8ea157cd4f835cd the build of Dirbaio's minimized example fails, whereas with b6dfaf4c291ee186481f6c1dcab03874d931c307 it succeeds.

Specifically, it seems to be this change: llvm/llvm-project@ebb326a#diff-efb0f6c06c654ed1044098de2bd75495d2fecd1730054dd26d41f0c9c93996e8R1582

If I revert that change (by simply changeing the if condition to if (false && activeProvideSym)) the example also succeeds to build again.

@jannic
Copy link
Contributor

jannic commented Oct 4, 2024

This seems to be enough to "fix" this issue:

--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1662,7 +1662,7 @@ Expr ScriptParser::readPrimary() {
     tok = unquote(tok);
   else if (!isValidSymbolName(tok))
     setError("malformed number: " + tok);
-  if (activeProvideSym)
+  if (false && activeProvideSym)
     ctx.script->provideMap[*activeProvideSym].push_back(tok);
   else
     ctx.script->referencedSymbols.push_back(tok);

I put "fix" in quotes because is not meant as a solution: I didn't even try to understand what the if/else branches are meant to do. So it's quite likely that I broke something else with this change.

(Verified on current LLVM main branch.)

@jonathanpallant
Copy link
Contributor Author

the next stable release is in 9 days, at which point I believe the Ferrous Systems Embedded Rust exercises will stop compiling.

@Mark-Simulacrum Mark-Simulacrum added this to the 1.82.0 milestone Oct 7, 2024
@Mark-Simulacrum Mark-Simulacrum added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example regression-untriaged Untriaged performance or correctness regression. labels Oct 7, 2024
@DianQK
Copy link
Member

DianQK commented Oct 8, 2024

Upstream issue: llvm/llvm-project#111478.

@Urhengulas
Copy link
Contributor

Urhengulas commented Oct 8, 2024

Is anyone aware of a workaround we could apply for defmt? We would like to avoid defmt being broken on stable with the Rust release next week.

I tried marking the defmt::default_panic function as pub, but this does not make a difference.

Is there something we can add to the linker script? Something along the lines of PLEASE_DONT_GARBAGE_COLLECT(__defmt_default_panic).

Or can we pretend that this function is in fact used?

Any pointer is much appreciated.

@skade
Copy link
Contributor

skade commented Oct 8, 2024

the next stable release is in 9 days, at which point I believe the Ferrous Systems Embedded Rust exercises will stop compiling.

Note that while the exercises are relatively small impact (as they are under our control), defmt is a widely popular solution in the embedded space.

@DianQK
Copy link
Member

DianQK commented Oct 8, 2024

I have read the related code, maybe we need to add this symbol to the symbol table. Or change the code like this:

diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 3febcfb87da4..44185c282ad7 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -1660,10 +1660,11 @@ Expr ScriptParser::readPrimary() {
     tok = unquote(tok);
   else if (!isValidSymbolName(tok))
     setError("malformed number: " + tok);
-  if (activeProvideSym)
+  if (activeProvideSym) {
     ctx.script->provideMap[*activeProvideSym].push_back(tok);
-  else
-    ctx.script->referencedSymbols.push_back(tok);
+    return [] { return 0; };
+  }
+  ctx.script->referencedSymbols.push_back(tok);
   return [=, s = ctx.script] { return s->getSymbolValue(tok, location); };
 }

However, I'm not familiar with this part of the code.

the next stable release is in 9 days, at which point I believe the Ferrous Systems Embedded Rust exercises will stop compiling.

Note that while the exercises are relatively small impact (as they are under our control), defmt is a widely popular solution in the embedded space.

In any case, I believe the upstream backport is likely to miss our backport process. I'm reverting this commit to our fork LLVM.

@Urhengulas
Copy link
Contributor

@DianQK said:

In any case, I believe the upstream backport is likely to miss our backport process. I'm reverting this commit to our fork LLVM.

Would this mean this issue will not land on stable? That would be great, then we do not need to find a workaround for defmt.

@apiraino
Copy link
Contributor

apiraino commented Oct 8, 2024

Note that while the exercises are relatively small impact (as they are under our control), defmt is a widely popular solution in the embedded space.

@rustbot label -P-medium +P-high

@skade
Copy link
Contributor

skade commented Oct 10, 2024

Most concrete binary projects of defmt are not public, but it has 415 reverse dependencies. https://crates.io/crates/defmt/reverse_dependencies. Multiple of those have about 1mio downloads. It has consistently over 10k daily downloads, showing active usage e.g. in CI/CD pipelines.

It is very widely used in embedded software.

@DianQK
Copy link
Member

DianQK commented Oct 10, 2024

The minimal reproduction is as follows:

main.rs:

#![no_main]
#![no_std]

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

#[no_mangle]
fn foo() {}

#[no_mangle]
fn bar() {}

script.t:

PROVIDE(foo = bar);
$ rustc +beta main.rs --target thumbv7em-none-eabihf -Clink-arg=-Tscript.t
error: linking with `rust-lld` failed: exit status: 1
  ...
  = note: rust-lld: error: script.t:1: symbol not found: bar
          rust-lld: error: script.t:1: symbol not found: bar
          rust-lld: error: script.t:1: symbol not found: bar
error: aborting due to 1 previous error

With small modifications, it can also be reproduced on x86.

@rustbot label +S-has-mcve +A-linkage

@rustbot rustbot added A-linkage Area: linking into static, shared libraries and binaries S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue labels Oct 10, 2024
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 11, 2024
Update LLVM submodule

Fixes (maybe after beta backport) rust-lang#131164.

r? nikic
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 11, 2024
Update LLVM submodule

Fixes (maybe after beta backport) rust-lang#131164.

r? nikic
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 12, 2024
Update LLVM submodule

Fixes (maybe after beta backport) rust-lang#131164.

r? nikic
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 12, 2024
Update LLVM submodule

Fixes (maybe after beta backport) rust-lang#131164.

r? nikic
@apiraino
Copy link
Contributor

I think this can be now closed, since #131448 has been backported and should have made it to the stable 1.82 release of tomorrrow.

Am I right @jonathanpallant ? Can you check if we're all good here? thanks :)

@Dirbaio
Copy link
Contributor

Dirbaio commented Oct 16, 2024

I can confirm nightly-2024-10-13 fixes it. nightly-2024-10-12 is the last one failing.

Beta works as well.

@DianQK
Copy link
Member

DianQK commented Oct 16, 2024

Upstream LLVM will not backport the relevant fixes, so I will add a test case.

@Urhengulas
Copy link
Contributor

Upstream LLVM will not backport the relevant fixes, so I will add a test case.

Do you think there is a chance that this "bug" will come back to us? We are currently evaluating if we should apply a fix/safeguard in defmt.

@DianQK
Copy link
Member

DianQK commented Oct 16, 2024

Upstream LLVM will not backport the relevant fixes, so I will add a test case.

Do you think there is a chance that this "bug" will come back to us? We are currently evaluating if we should apply a fix/safeguard in defmt.

No. The main branch of LLVM has fixed. The next major update will include it.

@Urhengulas
Copy link
Contributor

Upstream LLVM will not backport the relevant fixes, so I will add a test case.

Do you think there is a chance that this "bug" will come back to us? We are currently evaluating if we should apply a fix/safeguard in defmt.

No. The main branch of LLVM has fixed. The next major update will include it.

Perfect!

@thejpster
Copy link
Contributor

Lgtm

@jannic
Copy link
Contributor

jannic commented Oct 16, 2024

Also tried with the stable prerelease from https://internals.rust-lang.org/t/rust-1-82-0-pre-release-testing/21705. Problem is solved.

DianQK added a commit to DianQK/rust that referenced this issue Oct 22, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 22, 2024
Add a test case for rust-lang#131164

The upstream has already been fixed, but it won't be backported to LLVM 19.

r? jieyouxu or compiler
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 22, 2024
…iaskrgr

Rollup of 4 pull requests

Successful merges:

 - rust-lang#132002 (abi/compatibility: also test Option-like types)
 - rust-lang#132026 (analyse: remove unused uncanonicalized field)
 - rust-lang#132036 (Add a test case for rust-lang#131164)
 - rust-lang#132040 (relnotes: fix stabilizations of `assume_init`)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 23, 2024
Add a test case for rust-lang#131164

The upstream has already been fixed, but it won't be backported to LLVM 19.

r? jieyouxu or compiler

try-job: x86_64-gnu-stable
DianQK added a commit to DianQK/rust that referenced this issue Oct 23, 2024
fmease added a commit to fmease/rust that referenced this issue Oct 23, 2024
Add a test case for rust-lang#131164

The upstream has already been fixed, but it won't be backported to LLVM 19.

r? jieyouxu or compiler

try-job: x86_64-gnu-stable
fmease added a commit to fmease/rust that referenced this issue Oct 23, 2024
Add a test case for rust-lang#131164

The upstream has already been fixed, but it won't be backported to LLVM 19.

r? jieyouxu or compiler

try-job: x86_64-gnu-stable
bors added a commit to rust-lang-ci/rust that referenced this issue Oct 23, 2024
Rollup of 9 pull requests

Successful merges:

 - rust-lang#130991 (Vectorized SliceContains)
 - rust-lang#131928 (rustdoc: Document `markdown` module.)
 - rust-lang#131955 (Set `signext` or `zeroext` for integer arguments on RISC-V and LoongArch64)
 - rust-lang#131979 (Minor tweaks to `compare_impl_item.rs`)
 - rust-lang#132036 (Add a test case for rust-lang#131164)
 - rust-lang#132039 (Specialize `read_exact` and `read_buf_exact` for `VecDeque`)
 - rust-lang#132060 ("innermost", "outermost", "leftmost", and "rightmost" don't need hyphens)
 - rust-lang#132065 (Clarify documentation of `ptr::dangling()` function)
 - rust-lang#132066 (Fix a typo in documentation of `pointer::sub_ptr()`)

r? `@ghost`
`@rustbot` modify labels: rollup
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Oct 24, 2024
Rollup merge of rust-lang#132036 - DianQK:test-131164, r=jieyouxu

Add a test case for rust-lang#131164

The upstream has already been fixed, but it won't be backported to LLVM 19.

r? jieyouxu or compiler

try-job: x86_64-gnu-stable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. P-high High priority regression-from-stable-to-beta Performance or correctness regression from stable to beta. S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests