dtolnay/anyhow

backtrace seems to only work with opt-level=0

kurtbuilds opened this issue · 5 comments

This probably isn't a bug, but trying to understand how to use the library better.

In short, when I turn on backtrace feature, and build in dev, I get backtraces. However, running the same executable in release mode has the backtrace just return "unsupported backtrace". After a lot of debugging, I identified opt-level as the culprit. If I set it to zero, I get backtraces. They disappear even going to level=1.

See this repo for a minimum example: https://github.com/kurtbuilds/playground.git

In Cargo.toml, commenting in/out opt-level config changes the behavior.

I'm quite confused by this, since sources online say that backtraces are just configured by having debug symbols (debug = true), the RUST_BACKTRACE environ variable, and the backtrace feature in anyhow.


Is it by design that backtrace only works with opt-level=0? At the very least, I'm surprised this behavior isn't better documented: I can't find anything - on Google, Rust std docs, or anyhow - that mentions opt-level impacting backtraces. Are there plans to change this behavior?

I ran RUST_LIB_BACKTRACE=1 cargo run --release in your repo at kurtbuilds/playground@64b7026 and I get a backtrace.

   0: anyhow::error::<impl anyhow::Error>::msg
             at /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.72/src/error.rs:83:36
   1: playground::foo
             at ./src/main.rs:4:16
   2: playground::main
             at ./src/main.rs:8:13
   3: core::ops::function::FnOnce::call_once
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/core/src/ops/function.rs:250:5
   4: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/sys_common/backtrace.rs:135:18
   5: std::rt::lang_start::{{closure}}
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/rt.rs:166:18
   6: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/core/src/ops/function.rs:284:13
   7: std::panicking::try::do_call
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panicking.rs:524:40
   8: std::panicking::try
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panicking.rs:488:19
   9: std::panic::catch_unwind
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panic.rs:142:14
  10: std::rt::lang_start_internal::{{closure}}
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/rt.rs:148:48
  11: std::panicking::try::do_call
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panicking.rs:524:40
  12: std::panicking::try
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panicking.rs:488:19
  13: std::panic::catch_unwind
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/panic.rs:142:14
  14: std::rt::lang_start_internal
             at /rustc/32303b219d4dffa447aa606bc11c7a648f44a862/library/std/src/rt.rs:148:20
  15: main
  16: __libc_start_call_main
             at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  17: __libc_start_main_impl
             at ./csu/../csu/libc-start.c:392:3
  18: _start
rustc 1.73.0-nightly (32303b219 2023-07-29)
binary: rustc
commit-hash: 32303b219d4dffa447aa606bc11c7a648f44a862
commit-date: 2023-07-29
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 16.0.5

It looks like that only works on nightly.

10:01:11 kurt@arcticfox:~/work/playground $ RUST_LIB_BACKTRACE=1 cargo run --release
    Finished release [optimized + debuginfo] target(s) in 0.02s
     Running `/Users/kurt/.cache/cargo/target/release/playground`
unsupported backtrace
10:01:20 kurt@arcticfox:~/work/playground $ RUST_LIB_BACKTRACE=1 cargo +nightly run --release
   Compiling memchr v2.5.0
   Compiling libc v0.2.147
   Compiling cc v1.0.79
   Compiling gimli v0.27.3
   Compiling adler v1.0.2
   Compiling cfg-if v1.0.0
   Compiling anyhow v1.0.72
   Compiling rustc-demangle v0.1.23
   Compiling miniz_oxide v0.7.1
   Compiling object v0.31.1
   Compiling backtrace v0.3.68
   Compiling addr2line v0.20.0
   Compiling playground v0.1.0 (/Users/kurt/work/playground)
    Finished release [optimized + debuginfo] target(s) in 3.56s
     Running `/Users/kurt/.cache/cargo/target/release/playground`
   0: std::backtrace_rs::backtrace::libunwind::trace
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1: std::backtrace_rs::backtrace::trace_unsynchronized
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2: std::backtrace::Backtrace::create
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/backtrace.rs:332:13
   3: anyhow::error::<impl anyhow::Error>::msg
             at /Users/kurt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.72/src/error.rs:83:36
   4: playground::foo
             at ./src/main.rs:4:16
   5: playground::main
             at ./src/main.rs:8:13
   6: core::ops::function::FnOnce::call_once
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/core/src/ops/function.rs:250:5
   7: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/sys_common/backtrace.rs:135:18
   8: std::rt::lang_start::{{closure}}
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/rt.rs:166:18
   9: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/core/src/ops/function.rs:284:13
  10: std::panicking::try::do_call
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panicking.rs:500:40
  11: std::panicking::try
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panicking.rs:464:19
  12: std::panic::catch_unwind
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panic.rs:142:14
  13: std::rt::lang_start_internal::{{closure}}
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/rt.rs:148:48
  14: std::panicking::try::do_call
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panicking.rs:500:40
  15: std::panicking::try
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panicking.rs:464:19
  16: std::panic::catch_unwind
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/panic.rs:142:14
  17: std::rt::lang_start_internal
             at /rustc/6bba061467f7c2cab04b262b95eb67bf89265587/library/std/src/rt.rs:148:20
  18: _main

Is that expected? The docs say If using the nightly channel, or stable with features = ["backtrace"]: https://docs.rs/anyhow/latest/anyhow/

thomcc commented

I can't reproduce this on macOS with nightly or stable, release or debug.

thomcc commented

That said backtraces on macOS are a bit weird, we don't 100% support them, see https://github.com/rust-lang/backtrace-rs/blob/0533d475a52389ea0612b5543316bb571afc30ac/src/backtrace/libunwind.rs#L58-L72 So maybe this is related to that, although this shouldn't return unsupported (it's more a case where we return incorrect values for some frames).

I realized I was getting different behavior because I was using a different linker. Closing this, and thank you for help digging into this.