Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # 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