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

no_std panic=abort dev builds require rust_eh_personality #56152

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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