News for hackers. Stuff that matters.
Re:Making Rust binaries smaller by default by rfoo on Wednesday January 24, 2024 @04:27AM (#39115369)
opt-level = "z" may be slightly slower than O2/O3. lto = true and lto-units = 1 makes the final linking unbearably slow for large programs.

These are still okay, but then `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s.

Edit: and GP also used "panic-immediate-abort", which also removes the dependency to std::fmt::format!() because it now silently abort()s without even printing an error string.

Re:Making Rust binaries smaller by default by josephg on Wednesday January 24, 2024 @06:20AM (#39116012)
> These are still okay, but then `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s.

I just tried this. The stack traces on panic seem more or less the same with or without panic = "abort" in Cargo.toml.

For example, this program:

    fn main() {
        let v = vec![1, 2, 3];
        v[99];
    }
Compiled with panic="abort" outputs this stack trace:

    $ RUST_BACKTRACE=1 cargo run --release
      Compiling rust-panic v0.1.0 (/Users/seph/temp/rust-panic)
        Finished release [optimized] target(s) in 1.82s
        Running `target/release/rust-panic`
    thread 'main' panicked at src/main.rs:4:6:
    index out of bounds: the len is 3 but the index is 99
    stack backtrace:
      0: _rust_begin_unwind
      1: core::panicking::panic_fmt
      2: core::panicking::panic_bounds_check
      3: <alloc::vec::Vec<T,A> as core::ops::index::Index<I>>::index
      4: rust_panic::main
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    [1]    95405 abort      RUST_BACKTRACE=1 cargo run --release
Weirdly, in this test if I don't strip the binary, I get a larger binary size with panic="abort" than when I leave that out. That is surely due to a bug somewhere.
Re:Making Rust binaries smaller by default by ponkpanda on Wednesday January 24, 2024 @08:19AM (#39116939)
You're not adding the +nightly switch and the required flags to compiled std. Just setting panic=abort in cargo.toml isn't enough.

One can get binaries pretty damn small (low-mid tens of kilobytes for a basic cli program doing something like hashing of a file).

Problem I've found with manually compiling std (which has ancillary benefits of being able to compile to a specific uarch) is it can break the compilation process when bringing in third-party deps. The config.toml (stored in $PROJECT_ROOT/.cargo) overrides cargo's behaviour for all dependencies as well - which may break those compilations.

Tbh, it's one reason I don't particularly rate the rustc+cargo toolchain - but for most people writing regular applications: just being able to do ```cargo build -r``` and not care about binary size, uarch optimization or custom llvm/rustc optimizations (PGO etc), most won't care.

Re:Making Rust binaries smaller by default by lifthrasiir on Wednesday January 24, 2024 @06:23AM (#39116038)
> `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s.

I believe it does print backtraces then terminate, since the backtrace is printed via panic hooks, which happen before the actual unwinding.

Re:Making Rust binaries smaller by default by vacuity on Wednesday January 24, 2024 @01:20PM (#39120746)
Is the backtrace performed by the OS and that's why it still works? And the debug info needs to still be provided, just not an unwinding mechanism?
Re:Making Rust binaries smaller by default by exDM69 on Wednesday January 24, 2024 @04:36AM (#39115427)
Additionally the panic = "abort" disables stack unwinding, and running destructors when panic occurs, so it's a big change to the semantics of the program.

It's comparable to C++ land -fno-exceptions (not exactly, but similar).

Re:Making Rust binaries smaller by default by flohofwoe on Wednesday January 24, 2024 @04:42AM (#39115470)
IMHO when a piece of code decides to panic it should only happen when execution cannot continue under any circumstances, and in such cases all bets are off whether any cleanup code would actually still work. A hard abort might indeed be the best option.
Re:Making Rust binaries smaller by default by edflsafoiewq on Wednesday January 24, 2024 @05:22AM (#39115721)
That seems overly pessimistic (or perhaps overly optimistic about code that does not panic). Panics mostly exist to guard code from entering into such unrecoverable states, eg writing past the end of an array.
Re:Making Rust binaries smaller by default by flohofwoe on Wednesday January 24, 2024 @06:41AM (#39116150)
For me the difference would be: if the write past the array has been detected before it happens (via a range check) it would be a regular error which which can be handled, while a panic would be "oops somebody else has written past the end of the array" (e.g. a hitting a canary check), which should abort immediately because at that point it's no longer guaranteed that any recovery code would even work or just make things worse (e.g. trying to flush data from memory back to disk, but that data might have been corrupted too).
Re:Making Rust binaries smaller by default by lifthrasiir on Wednesday January 24, 2024 @07:24AM (#39116447)
You have a good point and lock poisoning had the same reasoning, but wasn't really popular [1]. (In hindsight the poisoning itself was a great idea but should have been decoupled from locks.) Compared to other languages with similar constructs, Rust panic is probably regarded as less fatal because an incorrect but safe Rust code tends to have a limited reach.

Ah, and it should be also noted that some non-fatal signals were also delivered only via panic. The best-known example is a memory allocation failure, which is recoverable in Rust but needed unwinding for a long time. Nowadays you have an unsafe but non-unwinding alternative.

[1] https://blog.rust-lang.org/2020/12/11/lock-poisoning-survey....

Re:Making Rust binaries smaller by default by edflsafoiewq on Wednesday January 24, 2024 @01:28PM (#39120858)
In Rust, out of bound array accesses are detected before they happen and handled by panicking.
Re:Making Rust binaries smaller by default by junon on Wednesday January 24, 2024 @04:38AM (#39115442)
Abort panic strategy is common in firmware and osdev, for anyone wondering if there are other use cases.