Skip to content

RUSTFLAGS=-Clink-dead-code breaks rustc build (alternatives?) #103064

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

Closed
AE1020 opened this issue Oct 14, 2022 · 2 comments
Closed

RUSTFLAGS=-Clink-dead-code breaks rustc build (alternatives?) #103064

AE1020 opened this issue Oct 14, 2022 · 2 comments

Comments

@AE1020
Copy link
Contributor

AE1020 commented Oct 14, 2022

I'm attempting to add instrumentation functions to rustc, to be called from the LLDB debug console. Here's a simple example of trying to add a C-style function and a Rust function to a hello world program:

#[no_mangle] #[allow(dead_code)]
pub extern "C" fn c_from_debugger_test() {
    println!("I am a c call from the debugger");
}

#[no_mangle] #[allow(dead_code)]
pub fn rust_from_debugger_test(num: u8) {
    println!("I am a rust {} call from the debugger", num);
}

fn main() {
    println!("Hello, I'm just a main()");
}

I built this with rustc -g hello.rs. Then with a breakpoint in main, at the LLDB debug console I tried:

> print c_from_debugger_test()
error: could not find item

> print rust_from_debugger_test(10)
error: could not find item

I had seen suggestions online that adding #[no_mangle] should be enough to get a function into the root set. That's echoed in comments at time of writing in the rust compiler sources at compiler/rustc_monomorphize/src/collector.rs:

//! ... (In eager
//! collection mode, during incremental compilation, all non-generic functions
//! are considered as roots, as well as when the `-Clink-dead-code` option is
//! specified. Functions marked `#[no_mangle]` and functions called by inlinable
//! functions also always act as roots.)

The functions would be included in the link if I instead built with rustc -g hello.rs -Clink-dead-code:

> print c_from_debugger_test()
(()) = () {}  // terminal shows "I am a c call from the debugger"

> print rust_from_debugger_test(10)
(()) = () {}  // terminal shows "I am a rust 10 call from the debugger"

Unfortunately... there are issues (e.g. #77529) with using -Clink-dead-code when building some codebases, and that includes building the rust compiler itself.

If I try building rustc with export RUSTFLAGS="-Clink-dead-code", this error stops the build (probably there would be others):

Compiling rustc-std-workspace-core v1.99.0 (/home/ae1020/rust/library/rustc-std-workspace-core)
thread 'rustc' panicked at 'called `Option::unwrap()` on a `None` value' 
    compiler/rustc_monomorphize/src/collector.rs:1379:36

(Coincidentally (?), that's the file with the comment about #[no_mangle] that I cite above.)

What I'm actually looking for is a way to add these root functions callable from the debugger to the rustc compiler...

  • Possible if #[no_mangle] caused functions to be considered live roots, as the comment suggests

    • If this is not true, should the comment be updated?
  • Possible if there was a way to build rustc using the RUSTFLAGS="-Clink-dead-code"

  • Perhaps there's another other trick or #[...] setting which could affect being included in the link?

(A workaround is to hack in spurious calls reachable from main() somewhere to the instrumentation functions.)

Meta

$ rustc --version --verbose
rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-unknown-linux-gnu
release: 1.64.0
LLVM version: 14.0.6
@AE1020 AE1020 added the C-bug Category: This is a bug. label Oct 14, 2022
@bjorn3
Copy link
Member

bjorn3 commented Oct 14, 2022

Without -Clink-dead-code=yes rustc will pass --gc-section to the linker. This will cause every symbol not reachable from an exported symbol to be omitted. In case of executables only main is exported unless -Z export-executable-symbols=yes is used.

Possible if #[no_mangle] caused functions to be considered live roots, as the comment suggests

If this is not true, should the comment be updated?

The comment is about the functions that will be codegened, not about those that end up in the final executable after whatever logic the linker uses to determine if functions should be kept.

@AE1020 AE1020 changed the title #[no_mangle] functions not linked w/o -Clink-dead-code (which fabricates errors) RUST_FLAGS=-Clink-dead-code breaks rustc build (alternatives?) Oct 15, 2022
@jyn514 jyn514 changed the title RUST_FLAGS=-Clink-dead-code breaks rustc build (alternatives?) RUSTFLAGS=-Clink-dead-code breaks rustc build (alternatives?) Apr 27, 2023
@Enselic
Copy link
Member

Enselic commented Jul 10, 2024

Triage: Seems like -Z export-executable-symbols=yes is the right solution here? Closing.

@Enselic Enselic closed this as not planned Won't fix, can't repro, duplicate, stale Jul 10, 2024
@fmease fmease removed C-bug Category: This is a bug. needs-triage-legacy labels Sep 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants