Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Make backtrace support optional #346

Open
purplesyringa opened this issue Jan 14, 2024 · 10 comments
Open

Make backtrace support optional #346

purplesyringa opened this issue Jan 14, 2024 · 10 comments

Comments

@purplesyringa
Copy link

I'm using anyhow for error management in an environment where I care about the binary size. Managing contexts explicitly lets me use rustc's panic=abort mode without significantly reducing ease of debugging, as the "stacktrace" is provided by anyhow. panic=abort would typically greatly reduce binary size because libunwind would no longer need to be linked in. However, anyhow still brings in std::backtrace, which relies on libunwind internally, reducing the benefits of panic=abort.

Would it be possible (or desired) to add an opt-in feature to avoid using std::backtrace, as if RUST_BACKTRACE=0 was always set? Alternatively, what about making backtrace an opt-out feature?

@purplesyringa
Copy link
Author

purplesyringa commented Jan 14, 2024

On a second thought, std pulls in libunwind even with panic=abort, so perhaps patching anyhow wouldn't achieve a thing. I guess this is blocked by rust-std support. I think I might try to fix that -- is anyone aware of an existing issue, by any change?

@purplesyringa
Copy link
Author

I just realized it isn't blocked by rust-std, actually. The same issue can be reproduced with panic_immediate_abort, in which case anyhow is the only dependency pulling in libunwind.

@vi
Copy link

vi commented Feb 7, 2024

Prior discussions: #239, #256.

Note: dependence on backtraces also complicate compilation on exotic targets that require -Zbuild-std and does not have backtrace-related symbols like _Unwind_Backtrace available out of the box.

@John-Nagle
Copy link

See this discussion on Rust forums. If panic tracebacks are enabled with RUST_BACKTRACE=1, anyhow starts attaching tracebacks to every Error object by default. The program cannot prevent this.

The whole idea that non-panic library behavior depends on an environment variable is just wrong. If you catch an error in code and handle it, the backtrace is useless, but uses time. Anything that does considerable network I/O and uses anyhow will generate large numbers of useless backtraces as it handles I/O errors.

On the forums, dumping "anyhow" and using "thiserror" has been suggested.

@jumpnbrownweasel
Copy link

jumpnbrownweasel commented Feb 29, 2024

I think it's very important that a library using anyhow can choose to disable backtraces without setting an env variable. Libraries should never set env variables for several reasons including 1) setting the variable impacts the app and its use of other libraries, 2) due to the UB warnings in set_var itself and the probability that set_var will be made unsafe in the future.

@purplesyringa
Copy link
Author

I've seen the argument that cargo features are opt-in, thus there can't be a feature that disables backtraces. I think that's a narrow way to view the problem. Indeed, std supports the panic_immediate_abort feature just fine. I think the main reason std has this allowance is that only the final bin crate is supposed to use this feature, after proving/verifying/assume the software works just fine without smart panic handling. Therefore, I believe a feature to disable backtrace could work just fine if it was explicitly documented to only be used by the bin crate.

@vi
Copy link

vi commented Feb 29, 2024

It may even be not a Cargo feature, just a custom cfg attribute, like Tokio's tokio_unstable.
That would prevent intermediate libraries setting this mode, and would require a dedicated compilation setting in project.

@jumpnbrownweasel
Copy link

The scenario I was referring to was where a library needs to avoid creation of backtraces in errors, and this should not be under the control of the app. The URLO discussion linked above was about this use case.

@John-Nagle
Copy link

Right. There are many uses of anyhow! that are not followed by an immediate abort. Capturing a backtrace is for unexpected program bugs. If a program handles an error, or just logs it, there's little need for a backtrace. Certainly not one that goes past the point where the error was handled.

@bjorn3
Copy link

bjorn3 commented Jun 19, 2024

If panic tracebacks are enabled with RUST_BACKTRACE=1, anyhow starts attaching tracebacks to every Error object by default.

RUST_LIB_BACKTRACE=0 should disable this. It can be set using std::env::set_var(), but be aware that in the next edition this function will be marked as unsafe due to not being thread safe on unix systems.

https://docs.rs/anyhow/latest/anyhow/struct.Error.html#method.backtrace

if you want only panics to have backtraces, set RUST_BACKTRACE=1 and RUST_LIB_BACKTRACE=0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants