sunfishcode / eyra

Rust programs written entirely in Rust
Other
773 stars 12 forks source link

`unwinding` dep features beneficial for `no_std` #51

Open polarathene opened 1 month ago

polarathene commented 1 month ago

I'm documenting this separately from my older issue comment that briefly mentioned the topic:


The current no_std example:

#![no_std]
#![no_main]
#![feature(lang_items)]
#![allow(internal_features)]

extern crate eyra;

#[no_mangle]
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    0
}

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }

#[global_allocator]
static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc;

#[lang = "eh_personality"]
extern "C" fn eh_personality() {}

Could presumably be simplified to:

#![no_std]
#![no_main]

extern crate eyra;

#[global_allocator]
static GLOBAL_ALLOCATOR: rustix_dlmalloc::GlobalDlmalloc = rustix_dlmalloc::GlobalDlmalloc;

#[no_mangle]
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    0
}

It's unclear to me if that is a customization a user can presently do via their Cargo.toml dependencies config, or if that clashes with the c-scape dependency config shown below.


Additional context

Extracted from: https://github.com/sunfishcode/eyra/issues/27#issuecomment-1820271259

eh_personality vs panic = "abort"

I was under the impression that eh_personality was not necessary when panic = "abort" is configured (even without related -Z build-std args?), but I guess that's something Rust implicitly handled with no_std on -gnu / -musl targets when building without Eyra? (EDIT: Yep, as referenced from Rust unstable book on lang-items)

This resource notes that panic = "abort" in Cargo.toml should disable unwinding and thus not require eh_personality? I can see from cargo tree that rustix is using the unwinding crate which provides a no_std compatible pure rust alternative, so perhaps this opt-out behaviour belongs upstream there?


$ cargo tree --invert unwinding

unwinding v0.2.2
├── c-scape v0.18.1
│   └── c-gull v0.18.1
│       └── eyra v0.17.0
│           └── example v0.1.0 (/example)
└── origin v0.20.2
    └── c-scape v0.18.1 (*)

https://crates.io/crates/unwinding#personality-and-other-utilities

_The library also provides Rust personality function. This can work with the unwinder described above or with a different unwinder. This can be handy if you are working on a #![no_std] binary/staticlib/cdylib and you still want unwinding support._

_If you are writing a #![no_std] program, simply enable personalitypanic-handler and system-alloc in addition to the defaults, you instantly obtains the ability to do unwinding!_

https://github.com/sunfishcode/c-ward/blob/aae71b8d3ce608a3ee3701b7646f345f1c649a27/c-scape/Cargo.toml#L45-L59

# Enable "libc" and don't depend on "spin".
# TODO: Eventually, we should propose a `fde-phdr-rustix` backend option to
# upstream `unwinding` so that it doesn't need to go through `dl_iterate_phdr`,
# but `fde-phdr-dl` works for now.
[target.'cfg(not(target_arch = "arm"))'.dependencies.unwinding]
version = "0.2.0"
default-features = false
features = [
    "unwinder",
    "dwarf-expr",
    "hide-trace",
    "fde-phdr-dl",
    "fde-registry",
    "libc",
]
sunfishcode commented 1 month ago

I've now released eyra 0.19, which has features "eh-personality" and "panic-handler", which enable the unwinding crate's personality function and panic handler, respectively. And "eh-personality-continue" and "panic-handler-trap" to have eyra provide stub implementations which can be useful if you know your code never unwinds or traps.

polarathene commented 1 month ago

Sorry for the delay in response, I haven't had time to come back and try the improvements out yet 😓

And "eh-personality-continue" and "panic-handler-trap" to have eyra provide stub implementations which can be useful if you know your code never unwinds or traps.

The documentation you added for these refer to no_std, but is it also applicable to -C panic=abort with std too?

Since the unwinding 0.2.3 release recently, I have been hitting some build failures:

https://github.com/nbdd0121/unwinding/issues/39#issuecomment-2423487325

The crate maintainer states that unwinding should not be used in this context, but it seems c-scape unconditionally depends on it? I'm not sure where this concern is meant to be resolved, so just making you aware of it.