Skip to content

no_std panic=abort dev builds require rust_eh_personality #56152

New issue

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

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

Already on GitHub? # to your account

Open
glandium opened this issue Nov 22, 2018 · 8 comments
Open

no_std panic=abort dev builds require rust_eh_personality #56152

glandium opened this issue Nov 22, 2018 · 8 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@glandium
Copy link
Contributor

$ cat Cargo.toml 
[package]
name = "foo"
version = "0.1.0"
authors = ["Mike Hommey <mh@glandium.org>"]

[lib]
crate-type = ["cdylib"]

[profile.dev]
panic = "abort"

[profile.release]
panic = "abort"
$ cat src/lib.rs
#![no_std]

use core::alloc::Layout;
use core::ffi::c_void;
use core::ptr;

const CHUNK_SIZE: usize = 1 << 20;

#[panic_handler]
#[no_mangle]
pub fn panic_impl(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

#[derive(Clone, Copy, Debug)]
pub(crate) struct ChunkLayout(Layout);

#[derive(Debug)]
pub(crate) struct ChunkLayoutErr;

impl ChunkLayout {
    fn from_size_align(size: usize, align: usize) -> Result<Self, ChunkLayoutErr> {
        if align < CHUNK_SIZE || (size & (CHUNK_SIZE - 1) != 0) {
            return Err(ChunkLayoutErr);
        }
        Layout::from_size_align(size, align).map(ChunkLayout).map_err(|_| ChunkLayoutErr)
    }
}

#[no_mangle]
pub unsafe extern "C" fn chunk_alloc_mmap(size: usize, align: usize) -> *mut c_void {
    if let Ok(_layout) = ChunkLayout::from_size_align(size, align) {
        ptr::null_mut()
    } else {
        ptr::null_mut()
    }
}
$ cargo build
   Compiling foo v0.1.0 (/tmp/foo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.24s
$ objdump -T target/debug/libfoo.so | grep rust_eh_personality
0000000000000000      D  *UND*	0000000000000000 rust_eh_personality

Practically speaking, this means the resulting library (cdylib) can't be loaded because the symbol can't be resolved.

This doesn't happen with --release (there is no undefined reference to rust_eh_personality). And this doesn't happen when the body of chunk_alloc_mmap is further reduced to only ptr::null_mut().

If I add -Wl,-Map,map to the linker arguments, the output map file says the symbol reference comes from:

 .data.DW.ref.rust_eh_personality
                0x0000000000004008        0x8 /tmp/foo/target/debug/deps/foo.3sp59mzlmyqssn40.rcgu.o
                0x0000000000004008                DW.ref.rust_eh_personality

So rust actively creates a pointer to rust_eh_personality in .data. DW suggests this would have something to do with DWARF, so I tried enabling debug info on the release profile, but that still didn't make it happen with --release.

Cc: @japaric, @alexcrichton

@glandium
Copy link
Contributor Author

This also happens with crate-type = ["staticlib"].

@alexcrichton
Copy link
Member

I believe this is already the case, but if you use a stock standard library (or libcore) the standard library is built with panic=unwind which causes the symbol to be referenced. The "solution" is to compile libcore/libstd as panic=abort

@jonas-schievink jonas-schievink added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-linkage Area: linking into static, shared libraries and binaries labels Mar 23, 2019
@rayanmargham
Copy link

Yes i've come across this issue today, so I think this needs more attention and someone to contribute to making a PR about it

@rayanmargham
Copy link

for now the fix is to use opt-level = 1 in the debug profile for the optimizer to optimize it out

@bjorn3
Copy link
Member

bjorn3 commented Jul 15, 2023

I think it would be possible to generate an aborting rust_eh_personality when compiling with -Cpanic=abort. I guess it could be part of the allocator shim to ensure it is generated only once.

@GrigorenkoPV
Copy link
Contributor

Came across this issue today. Really weird that it only manifests in debug builds.

@bjorn3
Copy link
Member

bjorn3 commented Nov 14, 2023

I would guess that the rust_eh_personality reference just so happens to get optimized away in release mode. There is no guarantee that this will remain the case in the future.

@saethlin
Copy link
Member

saethlin commented Sep 21, 2024

At time of writing, rust_eh_personality is actually optimized away on stable, but not on nightly. 🤦

searched nightlies: from nightly-2024-06-01 to nightly-2024-09-19
regressed nightly: nightly-2024-08-22
searched commit range: 5aea140...a32d4a0
regressed commit: 982c6f8

bisected with cargo-bisect-rustc v0.6.9

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start=2024-06-01 --end=2024-09-19 --script script 

Mea culpa, I guess.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants