Open yaahc opened 3 years ago
Can error types be !Send
and/or !Sync
?
Can error types be
!Send
and/or!Sync
?
yes, how does that apply here?
edit: actually, yes depending on what you mean by "be !Send". If you're referring to negative trait bounds then no, but if you mean can errors not implement Send
or Sync
and still implement the Error
trait then absolutely, though many parts of the ecosystem assume that all error types are Send + Sync + 'static
, so we advise against making errors that aren't Send
/Sync
/'static
, or at least suggest that you have a conversion method for getting an owned + Send + Sync version of those errors.
I just published mini-backtrace which allows capturing backtraces on no_std/embedded targets. It does not use any dynamic memory allocation, and resolving symbol names & line numbers is done offline using addr2line
.
Internally it uses LLVM's libunwind built with special flags and stripped of all OS/libc dependencies.
That's amazing @Amanieu, do you think the approach used in mini-backtrace
could eventually be applied upstream to std::backtrace::Backtrace
?
Not really, unwinding/backtraces fundamentally relies on some system-level support to locate unwinding information for the current binary. mini-backtrace
compiles its own libunwind with -D_LIBUNWIND_IS_BAREMETAL
which causes it to use the special symbols __exidx_*
to locate unwinding metadata in memory. This requires using special linker scripts to set up and only works for the main executable, not any shared libraries.
Resolving symbols and line numbers requires reading debuginfo which is not loaded to memory, which is not possible in no_std
. mini-backtrace
just punts symbol resolution to an offline step.
It would also be desirable to use something like this in signal handlers. This is sometimes[^1] supported by C/C++ backtrace libs (a concrete example is that abseil's has it) since otherwise it's dubious (very unsafe) to use in cases like a segfault handler that tells you where the bad pointer use happened.
It may be more trouble than it's worth though... It is certainly less critical for Rust, where bad pointer dereferences are not nearly as common.
[^1]: I almost said commonly here, but it's not clear to me if its actually commonly supported, or if people just commonly do it anyway. (Realistically, you can get away with doing a lot of signal-unsafe things in signal handlers...)
I'm currently using the libunwind project to backtrace in a signal handler since it's the only standalone one I'm aware of that claims to be async-signal safe. It would be amazing if the standard version offered that capability.
I'm currently using the libunwind project to backtrace in a signal handler since it's the only standalone one I'm aware of that claims to be async-signal safe.
It's not because it uses dl_iterate_phdr
from the dynamic linker to locate unwinding information. This function takes locks and allocates memory.
Yeah their documentation seems overly optimistic. Abseil's may be more accurate, but it appears to rely on frame pointers which is not really a realistic option unless you're building your entire userspace...
Right now
std
has proposed stabilizing a very minimal interface for capturing and printingBacktrace
s. However, internally it does not use this same interface in it's own panic hook. Internally, instead of capturing aBacktrace
object and then printing it std directly invokes a function that prints the backtrace without capturing or resolving frames in advance (source). This interface apparently uses much less memory (does it allocate heap memory at all?).Other contributors to the project have expressed a desire for a lightweight backtrace printing interface they can use from signal handlers and the like (source). The above interface doesn't seem to work in this specific scenario, but we may want to look into what would be needed to print a backtrace from a signal handler, and in the future possibly expose alternate interfaces to printing backtraces that could work in these constrained environments.