backtrace-rs icon indicating copy to clipboard operation
backtrace-rs copied to clipboard

[feat] should document on how to support backtrace when size optimize

Open loynoir opened this issue 1 year ago • 3 comments

feat

should document on how to support backtrace when size optimize

reproduce

fn show_backtrace() {
    let backtrace = backtrace::Backtrace::new();
    eprintln!("backtrace::Backtrace {:?}", backtrace);
}

fn f4() {
    show_backtrace()
}

fn f3() {
    f4()
}

fn f2() {
    f3()
}

fn f1() {
    f2()
}

fn main() {
    f1()
}

actual

When use size optimize config, backtrace is not working.

[profile.reproduce]
inherits = "release"

debug = false
strip = true
backtrace::Backtrace    0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: __libc_start_main
   5: <unknown>

544K    bt

When use backtrace working config, size is much larger than size optimize config.

[profile.reproduce]
inherits = "release"

debug = true
strip = false
backtrace::Backtrace    0: bt::show_backtrace
             at /path/to/reproduce/src/bin/bt.rs:2:21
      bt::f4
             at /path/to/reproduce/src/bin/bt.rs:7:5
      bt::f3
             at /path/to/reproduce/src/bin/bt.rs:11:5
      bt::f2
             at /path/to/reproduce/src/bin/bt.rs:15:5
      bt::f1
             at /path/to/reproduce/src/bin/bt.rs:19:5
      bt::main
             at /path/to/reproduce/src/bin/bt.rs:23:5
   1: core::ops::function::FnOnce::call_once
             at /rustc/9b72238eb813e9d06e9e9d270168512fbffd7ee7/library/core/src/ops/function.rs:250:5
      std::sys::backtrace::__rust_begin_short_backtrace
             at /rustc/9b72238eb813e9d06e9e9d270168512fbffd7ee7/library/std/src/sys/backtrace.rs:154:18
   2: main
   3: <unknown>
   4: __libc_start_main
   5: _start

5.4M    bt

expected

Should document on how to find a balance like something like below.

[profile.reproduce]
inherits = "release"

debug = false_but_keep_user_backtrace
strip = true_but_not_user_backtrace
backtrace::Backtrace    0: bt::show_backtrace
             at /path/to/reproduce/src/bin/bt.rs:2:21
      bt::f4
             at /path/to/reproduce/src/bin/bt.rs:7:5
      bt::f3
             at /path/to/reproduce/src/bin/bt.rs:11:5
      bt::f2
             at /path/to/reproduce/src/bin/bt.rs:15:5
      bt::f1
             at /path/to/reproduce/src/bin/bt.rs:19:5
      bt::main
             at /path/to/reproduce/src/bin/bt.rs:23:5
   **/rustc/xxx are not kept **
   **main, <unknown>, __libc_start_main, _start are not kept**

544K    bt

loynoir avatar Sep 29 '24 03:09 loynoir

You can use strip = "debuginfo" to strip all debuginfo, but keep the symbols used for backtraces. In fact this is the default for release mode nowadays. Symbols are a lot smaller than debuginfo, so unless you really need every last kb of space, you should probably use strip = "debuginfo".

bjorn3 avatar Sep 29 '24 11:09 bjorn3

But, f1 f2 f3 f4 are still missing.

[profile.reproduce]
inherits = "release"

debug = true
strip = "debuginfo"
backtrace::Backtrace    0: bt::main
   1: std::sys::backtrace::__rust_begin_short_backtrace
   2: main
   3: <unknown>
   4: __libc_start_main
   5: _start

620K    bt

loynoir avatar Sep 29 '24 13:09 loynoir

They probably got inlined. Full debuginfo also keeps information about inlined functions, but most of the time backtraces are legible without this information anyway and even with full debuginfo the compiler may replace tail calls with jumps, which would irrecoverably lose the stack frame for the caller.

bjorn3 avatar Sep 29 '24 13:09 bjorn3

You asked for less than the whole enchilada, so you got less than the whole enchilada. Working as intended.

workingjubilee avatar Jan 03 '25 09:01 workingjubilee

Or, alternatively:

strip = true_but_not_user_backtrace exists, it's called strip = false. Everything more will affect backtraces.

Noratrieb avatar Jan 03 '25 09:01 Noratrieb