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

Doesn't build in no_std env but it seems like it is supposed to build there

Open phip1611 opened this issue 3 years ago • 4 comments

I wanted to use this library in a no_std environment, but it doesn't compile because of the miniz_oxide crate. If I see it correctly in Cargo.toml and lib.rs, this crate is supposed to work in no_std-environments.

I'd like to propose the following changes:

  1. clarify in README.md if this crate actually supports no_std and what one has to do for it
  2. if this is a bug, please fix it and perhaps add some CI which covers this in the future

The build error for my x86_64 no_std-target is:

Compiling miniz_oxide v0.4.4
error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-unknown-hedron-5835702812158589728` target may not support the standard library
  = note: `std` is required by `miniz_oxide` because it does not declare `#![no_std]`
  = help: consider building the standard library from source with `cargo build -Zbuild-std`

For more information about this error, try `rustc --explain E0463`. 

phip1611 avatar Sep 19 '21 18:09 phip1611

It can't work in no_std environments as it depends on the standard library to load debuginfo, on libc/winapi to get information about where each dylib is loaded and libunwind/winapi to get a raw backtrace in the first place.

What is the exact use case you have?

bjorn3 avatar Sep 19 '21 18:09 bjorn3

I'm developing a bare-metal x86_64 binary, or better to say the initial roottask running under a microkernel. If I have a callstack of a -> b -> c, I'd like that something like backtrace_to_string(&mut buf) inside c gives me

0x000abc: function a
0x000ccc: function b
0x000fff: function c

I think this should be possible with no_std because one has "just to walk up the stack frame". I guess with the relevant information standing in .eh_frame section inside the ELF, all relevant information are available to do that. I'm not into it but I guess it should be possible.

Why does this lib has #![no_std] then? https://github.com/rust-lang/backtrace-rs/blob/master/src/lib.rs#L91

phip1611 avatar Sep 21 '21 06:09 phip1611

Looks like without libstd it can still somewhat work, but I think it isn't able to show symbol names and source locations in that case. Only addresses: https://github.com/rust-lang/backtrace-rs/blob/cc89bb66f91b2b4a640b0b525ca5d753e3346d7e/Cargo.toml#L66

I am pretty sure it still requires libunwind when the std feature is disabled.

I think this should be possible with no_std because one has "just to walk up the stack frame". I guess with the relevant information standing in .eh_frame section inside the ELF, all relevant information are available to do that. I'm not into it but I guess it should be possible.

Under non-kernel conditions there may be multiple .eh_frame sections. One for the main executable and one for each dylib. To locate them the unwinder needs help from libc.

For a kernel unwinder you could use something like redox-os' kernel unwinder: https://gitlab.redox-os.org/redox-os/kernel/-/blob/master/src/arch/x86_64/interrupt/trace.rs It requires frame pointers, but it is much simpler than a full dwarf unwinder (.eh_frame)

Alternatively you could use this crate as pure-rust no_std compatible unwinder: https://github.com/nbdd0121/unwind

bjorn3 avatar Sep 21 '21 07:09 bjorn3

This crate does build for no_std in CI, but I'm not sure how well that checks that its dependencies support no_std. The miniz_oxide error is because you don't have alloc, and backtrace-rs requires alloc too, at least for DWARF symbolization.

Maybe https://github.com/Amanieu/mini-backtrace works for your use.

Why does this lib has #![no_std] then?

Looking at the history, it was added in #126 for the purpose of making this crate a dependency of libstd, and that is still the reason.

philipc avatar Sep 21 '21 07:09 philipc