Backtrace libstd runtime enable/disable

Hello. I don't know is it right place to post, or I should add comment to RFC-2504 or create new RFC instead?

I've been looking through std::backtrace::Backtrace and noticed that it is configured using env variable and content of the variable is cached for obvious reasons (performance).

impl Backtrace {
    /// Returns whether backtrace captures are enabled through environment
    /// variables.
    fn enabled() -> bool {
        // Cache the result of reading the environment variables to make
        // backtrace captures speedy, because otherwise reading environment
        // variables every time can be somewhat slow.
        static ENABLED: AtomicUsize = AtomicUsize::new(0);
        match ENABLED.load(SeqCst) {
            0 => {}
            1 => return false,
            _ => return true,
        }
        let enabled = match env::var("RUST_LIB_BACKTRACE") {
            Ok(s) => s != "0",
            Err(_) => match env::var("RUST_BACKTRACE") {
                Ok(s) => s != "0",
                Err(_) => false,
            },
        };
        ENABLED.store(enabled as usize + 1, SeqCst);
        enabled
    }

But I have one use case and request for change. I would like to be able to switch backtrace in runtime.

When it could be needed? Production use on the server, when sys-admin detected incorrect behavior or developer want to detect why Error was returned. So it would be really useful to change backtrace behaviour of error at run-time.

  1. notice error in logs
  2. call private API (or debug button if UI app) and receive backtraces till disabled.

So the application user won't have the overhead of backtrace until it's required.

What I propose

Add setter method: Backtrace::set_enabled() and make ENABLED: AtomicUsize non static inside function but just private.

The default behavior is still to check env-variable, but it could be overridden by the programmer.

P.S. do I understand correctly that RUST_BACKTRACE would affect backtraces of panics and it's possible to set RUST_BACKTRACE=1 RUST_LIB=BACKTRACE=0. meaning that panics would print backtrace and Errors won't have backtrace?

2 Likes

Another benefit is that you would be able to put this option into your app's configuration file (or any other unified source of configuration) instead of requiring an environment variable.

2 Likes

BUMP.

So no interest in this? perhaps I'll post a comment in existing RFC then.

You can already use std::panic::set_hook to have whatever backtrace behavior you want.

That's only for panic backtraces, if you're using error backtraces too (on nightly) it'd be nice to be able to toggle them too. (In fact, toggling those is much more useful since capturing backtraces on errors can be much more expensive).

1 Like

You can use Backtrace::{force_capture, disabled} and again do whatever you want to control which is called.

Not when it’s other libraries that are capturing the backtrace. I guess someone could publish some backtrace-toggle crate and try to get that widely used in the ecosystem in all error implementations, but it seems so much more useful for that to be builtin to std so that libraries can just call Backtrace::capture unconditionally and have the application control that.

But you don't have control over library code. Main point of nightly feature of stack-trace capture is to help troubleshoot app. If enabled all Error's would have stack-trace, but it's quite expensive.

1 Like