-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[AVR] undefined reference to 'abort' on static mutable variable #139737
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
Comments
Here's a minimal repo to reproduce the issue https://github.com/EvansJahja/avr_undefined_abort EDIT: other example https://github.com/EvansJahja/avr_undefined_abort/tree/no_alloc |
The failure disappears when using The failure only happens when using |
Regardless of |
Current workaround #[unsafe(no_mangle)]
pub unsafe extern "C" fn abort() -> !{
loop {}
} |
Update: another example without alloc Changing |
I think LLVM lowers trap instructions to calls of the |
That makes sense, but I'm under the assumption that avr builds with libgcc which should have the |
Minimized: #![no_main]
#![no_std]
use core::hint::unreachable_unchecked;
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_: &PanicInfo) -> ! {
loop {}
}
#[unsafe(no_mangle)]
fn main() -> ! {
unsafe {
unreachable_unchecked();
}
loop {
//
}
}
I don't think this is a bug - it's just that under some conditions (in particular when compiling without optimizations), llvm will insert a special panic-like instruction (aka trap) for code paths it thinks are unreachable, to be 250% sure they aren't reached. You can observe this behavior for other architectures as well - e.g. on x86 this: #[inline(never)]
pub fn foo() {
unsafe {
core::hint::unreachable_unchecked();
}
} ... gets compiled into: playground::foo:
ud2 ... with Since AVRs are simpler than your typical x86 processor, they don't have an equivalent of #[unsafe(no_mangle)]
pub unsafe extern "C" fn abort() -> ! {
// loop {}, blink, panic!() etc.
} 99% of time you don't have to worry about this, because the optimizer gets rid of those potentially-undefined code paths whatsoever, but 1% of the time they are left and it's up to you to decide what you want to happen then. So tl;dr not a bug - at the same time, I understand that 99% of people don't want to be bothered with this, "do whatever" will work just fine for them; I think we might be able to get the best of both worlds (provide a default function, but allow to overwrite it) by utilizing weak symbols (we'd create a weak I'll experiment and report back. |
for me it's not about "do whatever". We're in no_std land so I had to put my own panic_handler anyway, like we get compiler errors if we don't specify a panic handler, but didn't realize that we need to implement abort too. |
I tried this code:
I expected to see this happen: compile successfully
Instead, this happened: error because "undefined reference to `abort'"
Meta
rustc --version --verbose
:Backtrace
The text was updated successfully, but these errors were encountered: