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

Building no_std binary fails with link error "undefined reference to `__rust_probestack" #43264

Closed
ranweiler opened this issue Jul 16, 2017 · 8 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug.

Comments

@ranweiler
Copy link
Contributor

Platform

  • Rust nightly, version: rustc 1.20.0-nightly (086eaa78e 2017-07-15)
  • OS: Linux 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u2 (2017-06-26) x86_64 GNU/Linux

Summary

Compilation of a no_std binary on nightly fails with a linking error about the new stack probe feature.

Expected: The binary builds successfully, and rustc links to the new __rust_probestack implementation for my platform.

Observed: Building fails with a link error: undefined reference to `__rust_probestack'

Comments

I poked around the Rust source and recent PRs around stack probes, and the feature didn't seem to be configurable. Things that would be nice: the ability to toggle stack probes with a -C flag, or to have a configurable language item, like we do for eh_personality and panic_fmt. I have not yet tried to work around this with linker arguments, as it is more of a weird edge case I ran into in some throwaway example code.

Question

Is there a reason this behavior is expected, and linking shouldn't just work?

Test case

The issue can be reproduced using the following project:

Cargo.toml:

[package]
name = "example"
version = "0.1.0"

[dependencies]
libc = { version = "0.2.11", default-features = false }

and src/main.rs:

#![feature(lang_items)]
#![feature(start)]
#![no_std]
extern crate libc;

// const SIZE: usize = 2008; // This is a threshold. The project successfully builds.
const SIZE: usize = 2009; // This is the smallest array size which triggered a failure.

struct S { data: [u8; SIZE] }

#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
    let s = S { data: [0; SIZE] };
    0
}

#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop {} }

Output

Full error from cargo build:

$ cargo build --verbose
       Fresh libc v0.2.26
   Compiling example v0.1.0 (file:///home/joe/src/example)
     Running `rustc --crate-name example src/main.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9cb543322668ed58 -C extra-filename=-9cb543322668ed58 --out-dir /home/joe/src/example/target/debug/deps -L dependency=/home/joe/src/example/target/debug/deps --extern libc=/home/joe/src/example/target/debug/deps/liblibc-d2ff9e092d4e994b.rlib`
warning: field is never used: `data`
 --> src/main.rs:9:12
  |
9 | struct S { data: [u8; SIZE] }
  |            ^^^^^^^^^^^^^^^^
  |
  = note: #[warn(dead_code)] on by default

warning: unused variable: `s`
  --> src/main.rs:13:9
   |
13 |     let s = S { data: [0; SIZE] };
   |         ^
   |
   = note: #[warn(unused_variables)] on by default

error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/joe/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/joe/src/example/target/debug/deps/example-9cb543322668ed58.0.o" "-o" "/home/joe/src/example/target/debug/deps/example-9cb543322668ed58" "-Wl,--gc-sections" "-pie" "-nodefaultlibs" "-L" "/home/joe/src/example/target/debug/deps" "-L" "/home/joe/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/home/joe/src/example/target/debug/deps/liblibc-d2ff9e092d4e994b.rlib" "/home/joe/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-225cf0734ab321d6.rlib" "-Wl,-Bdynamic" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util"
  = note: /home/joe/src/example/target/debug/deps/example-9cb543322668ed58.0.o: In function `example::start':
          /home/joe/src/example/src/main.rs:12: undefined reference to `__rust_probestack'
          collect2: error: ld returned 1 exit status
          

error: aborting due to previous error

error: Could not compile `example`.

Caused by:
  process didn't exit successfully: `rustc --crate-name example src/main.rs --crate-type bin --emit=dep-info,link -C debuginfo=2 -C metadata=9cb543322668ed58 -C extra-filename=-9cb543322668ed58 --out-dir /home/joe/src/example/target/debug/deps -L dependency=/home/joe/src/example/target/debug/deps --extern libc=/home/joe/src/example/target/debug/deps/liblibc-d2ff9e092d4e994b.rlib` (exit code: 101)
@Mark-Simulacrum
Copy link
Member

cc @alexcrichton

@Mark-Simulacrum Mark-Simulacrum added the A-linkage Area: linking into static, shared libraries and binaries label Jul 19, 2017
@alexcrichton
Copy link
Member

@ranweiler as a no_std binary this is missing the compiler_builtins crate which is where these intrinsics come from.

If you follow these instructions does that solve your problem?

@ranweiler
Copy link
Contributor Author

@alexcrichton, yes, the instructions at your link resolved the link error. Thank you!

Also, looks like it is sufficient to add #![feature(compiler_builtins_lib)] and extern crate compiler_builtins; to my main.rs. Adding the explicit Cargo dependency is not necessary. I'm assuming this just uses the active toolchain's version of compiler_builtins.

For the reference of others, I've found (indirect) documentation for the reported situation here: https://doc.rust-lang.org/unstable-book/library-features/compiler-builtins-lib.html

The documentation I was working from included this section of the Unstable Book: "Writing an executable without stdlib", which doesn't mention this feature at all.

  1. Should users writing no_std binaries always use this feature/crate?
  2. Should we add a comment about the compiler_builtins_lib feature to the above docs on writing a no_std executable?

@alexcrichton
Copy link
Member

Ok cool, glad that worked out! This is an interesting case though in terms of documentation and embedding and whatnot. In the limit it's true that all binaries should use this crate unconditionally, but for specific really tiny embedded projects it may want to be avoided for one reason or another.

My recommendation though would be that we should definitely update the docs to mention this!

@ranweiler
Copy link
Contributor Author

@alexcrichton, great, and thanks so much for the help! I'm happy to open a PR for the docs, too.

@alexcrichton
Copy link
Member

That'd be awesome, thanks! Feel free to r? me on the PR and I can take a look

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jul 24, 2017
…ichton

Document use of `compiler_builtins` with `no_std` binaries

See discussion in rust-lang#43264.

The docs for the `compiler_builtins_lib` feature were removed in
PR rust-lang#42899. But, though the `compiler_builtins` library has been
migrated out-of-tree, the language feature remains, and is needed to
use the stand-alone crate. So, we reintroduce the docs for the
feature, and add a reference to them when describing how to create a
`no_std` executable.
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 28, 2017
@FiloSottile
Copy link

FWIW, this (along with #38281) is very hard to discover when trying to just make a simple no_std staticlib, partially because it's unclear what the entry point docs are for no_std (I ended up starting from an old version of the book).

@Enselic
Copy link
Member

Enselic commented Sep 15, 2023

Triage: Closing as fixed since the originally reported issue was fixed by improving docs. If there is still (6 years later) something that should be done, it is better to file a new issue for that issue with up to date information.

@Enselic Enselic closed this as completed Sep 15, 2023
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 C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

5 participants