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

Rust with [no_std] & CustomAllocator -> rust_oom either undefined in link stage or already defined in compile stage :/ #63348

Open
2ndTaleStudio opened this issue Aug 7, 2019 · 3 comments
Labels
A-allocators Area: Custom and system allocators A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-bare-metal Target: Rust without an operating system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@2ndTaleStudio
Copy link

Hi there,

i'm a bit new to rust and writing a library for embedded Raspberry Pi bare metal programming. I'm completely using #![no_std] in all of my crates. However, at a certain point functions of the alloc crate are needed. So I came accross the option to implement a custom GlobalAllocator as per the doc: (https://doc.rust-lang.org/core/alloc/trait.GlobalAlloc.html).

However, when compiling this the crate also requires an alloc_error_handler present like so:

#![no_std]
#![feature(alloc_error_handler)]

#[global_allocator]
static ALLOCATOR: RusPiRoAllocator = RusPiRoAllocator;
[...] here comes the implementation of the allocator [...]
#[alloc_error_handler]
fn alloc_error_handler(_: Layout) -> ! {
    // TODO: how to handle memory allocation errors?
    loop { }
}

However, doing so compilation works fine, but using this crate in an actual binary to be build as a dependency lead to the linker error undefined reference to 'rust_oom'.

So well I just put this into the code as well:

#[alloc_error_handler]
fn alloc_error_handler(_: Layout) -> ! {
    // TODO: how to handle memory allocation errors?
    loop { }
}

#[no_mangle]
fn rust_oom() -> ! {
    // well, currently there is nothing we could do on out-of-memory other than halt the core
    loop { }
}

BUT, doing so the compiler complains that the function rust_oom has already being defined. So for whatever reason the compiler seem to optimize the rust_oom function away before linking. As a workaround I put the rust_oom function into a separate crate the allocator crate depends on. (you can find the whole code here: ruspiro-allocator.

With this workaround in place the building of the binary works fine as long as the ruspiro-allocator crate is a direct dependency of it. I would rather like to bundle other crates of mine into a new crate that makes it easier to consume and may need only one dependency in the binary to be created with some feature gates but not many...

So I created a crate, lets call it kernel-crate that represents the final binary to be build. This crate has a dependency to a library-crate which depends on allocator-crate.
In this scenario the linker will again complain that the reference to rust_oom is undefined. So somewhere down the route the function seem to be optimized away again...
But if kernel-crate directly depends on allocator-crate everything works fine....

I would appreciate if someone could shed a light on the issue and how to solve it properly.

Btw. I'm building for the target armv7-unknown-linux-gnueabihf, cross compiling from a windows host machine with cargo version:

cargo 1.38.0-nightly (677a180f4 2019-07-08)

Any hint would be much appreciated...
Thanks in advance.

@hellow554
Copy link
Contributor

The issue tracker is for reporting errors in the compiler or language itself. If you need help with something, just go to the user forum at https://users.rust-lang.org or https://stackoverflow.com/questions/tagged/rust .

@2ndTaleStudio
Copy link
Author

2ndTaleStudio commented Aug 7, 2019

Hi,
sorry if I used this channel the wrong way.
However,l for me it pretty much feels like an issue with the compiler or linker and how the rust_oom function is implemented and suddenly stripped away by the compiler. I mean, why is not having the function leads to "undefined reference" but implementing it at the right place leads to "symbol already defined" ? Don't you think this is a bug in the compiler?

@jonas-schievink jonas-schievink added A-allocators Area: Custom and system allocators A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 7, 2019
@workingjubilee workingjubilee added the O-bare-metal Target: Rust without an operating system label Aug 17, 2022
@bjorn3
Copy link
Member

bjorn3 commented Jul 13, 2023

#112331 will probably fix this as side effect once it gets merged if this issue still exists at all. With that PR #[alloc_error_handler] and rust_oom no longer exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-allocators Area: Custom and system allocators A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. O-bare-metal Target: Rust without an operating system 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

5 participants