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

Panic related strings are still in binary with custom panic_fmt #47526

Open
pepyakin opened this issue Jan 17, 2018 · 5 comments
Open

Panic related strings are still in binary with custom panic_fmt #47526

pepyakin opened this issue Jan 17, 2018 · 5 comments
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-heavy Issue: Problems and improvements with respect to binary size of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-embedded Working group: Embedded systems

Comments

@pepyakin
Copy link
Contributor

pepyakin commented Jan 17, 2018

It seems that custom panic_fmt that doesn't touches Arguments doesnt not help to strip all panic-related strings from final binary while compiling to wasm (either emscripten or wasm32-unknown-unknown)

#![feature(lang_items)]
#![no_std]
#![no_main]

extern "C" {
    fn halt();
}

#[no_mangle]
#[lang = "panic_fmt"]
pub extern "C" fn panic_fmt(
    _args: ::core::fmt::Arguments,
    _file: &'static str,
    _line: u32,
    _col: u32,
) -> ! {
    loop { 
        unsafe { halt() }
    }
}

#[lang = "eh_personality"] extern fn eh_personality() {}

#[no_mangle]
pub fn call(descriptor: u8) -> u8 {
    assert!(descriptor > 0);
    descriptor
}

Invocation:
rustc --target=wasm32-unknown-emscripten --emit llvm-ir -C lto -C opt-level=3 src/main.rs

$ rustc --version
rustc 1.24.0-nightly (1956d5535 2017-12-03)

this produces the following LLVM IR.

The problem is that panic_fmt is not using it's _args, so it is a dead arg. However, despite this, strings for panic messages are still end up in the LLVM IR}.

It seems that running opt -deadargelim -globaldce helps to strip this strings.

@gamozolabs
Copy link

gamozolabs commented Jan 17, 2018

Somewhat related #47409

Using -C lto and -Z thinlto=off should allow a workaround here.

I think at some point in the past the issue seemed to be due to the fact that panic_fmt is extern and it was not optimized across that boundary. However I could be misremembering, I don't have my test case.

-B

@pepyakin
Copy link
Contributor Author

Compiling with this

rustc --target=wasm32-unknown-unknown --emit llvm-ir -C lto -C opt-level=3 -Z thinlto=off src/main.rs

doesn't seem to resolve the issue: the strings are still there.

@pietroalbini pietroalbini added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. O-wasm Target: WASM (WebAssembly), http://webassembly.org/ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 23, 2018
@pepyakin
Copy link
Contributor Author

pepyakin commented Jan 31, 2018

@pietroalbini To clarify, this isn't about wasm only.

compiling with

# halt.o contains symbo `_halt`: just an empty function.
rustc --crate-type=cdylib -C lto -C opt-level=3 main.rs -C link-arg=halt.o

will still produce these strings in binary:

$ strings ./libmain.dylib
assertion failed: descriptor > 0main.rs

@pietroalbini pietroalbini removed the O-wasm Target: WASM (WebAssembly), http://webassembly.org/ label Jan 31, 2018
@stephank
Copy link

When using Cargo, this is also leaking full filesystem paths into binaries for assertions in dependencies. ($HOME/.cargo/registry/src/...)

It'd be nice if those strings could be cleaned up to something like ~some-dep/src/lib.rs, even for projects with the default panic = "unwind", to not leak info about the build system in distributables. But I guess that is a separate issue.

I've been trying to work around this issue in my current project. I don't know how to make Cargo do the equivalent of opt -deadargelim -globaldce. I tried:

$ cargo rustc -vv --lib --release --target wasm32-unknown-unknown -- -C passes='deadargelim globaldce'

But that appears to not help, perhaps because cargo rustc passes those arguments only to the final compile/link step?

I also tried doing the following, but the spaces apparently break a generated command somewhere:

$ RUSTFLAGS="-C passes='deadargelim globaldce'" cargo build -vv --release --target wasm32-unknown-unknown
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `rustc - --crate-name ___ --print=file-names -C passes='deadargelim globaldce' --target wasm32-unknown-unknown --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro` (exit code: 101)
--- stderr
error: multiple input filenames provided

Is there some way to make this work?

I also tried building a custom libcore, hacking the panic macros to throw away args and abort(). That takes care of most of it, but still leaks filenames for calls to panic_bounds_check generated by the compiler.

@pepyakin
Copy link
Contributor Author

I've been trying to work around this issue in my current project. I don't know how to make Cargo do the equivalent of opt -deadargelim -globaldce. I tried:

I also was unable to pass these options via rustc command lines. It only worked if I invoke the opt command separately.

@jonas-schievink jonas-schievink added I-heavy Issue: Problems and improvements with respect to binary size of generated code. WG-embedded Working group: Embedded systems labels Apr 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-enhancement Category: An issue proposing an enhancement or a PR with one. I-heavy Issue: Problems and improvements with respect to binary size of generated code. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-embedded Working group: Embedded systems
Projects
None yet
Development

No branches or pull requests

5 participants