-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.Category: This is a bug.O-AVRTarget: AVR processors (ATtiny, ATmega, etc.)Target: AVR processors (ATtiny, ATmega, etc.)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
I tried this code:
pub static mut STATMUT : Option<String> = None;
#[unsafe(no_mangle)]
fn main() -> (){
unsafe {
STATMUT = Some(String::from_str("hello").unwrap());
}
loop {}
}
I expected to see this happen: compile successfully
Instead, this happened: error because "undefined reference to `abort'"
Meta
rustc --version --verbose
:
rustc 1.88.0-nightly (9ffde4b08 2025-04-12)
binary: rustc
commit-hash: 9ffde4b089fe8e43d5891eb517001df27a8443ff
commit-date: 2025-04-12
host: x86_64-pc-windows-msvc
release: 1.88.0-nightly
LLVM version: 20.1.2
Backtrace
Compiling avr_undefined_abort v0.1.0 (C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort)
warning: unused variable: `layout`
--> src\main.rs:14:28
|
14 | unsafe fn alloc(&self, layout: core::alloc::Layout) -> *mut u8 {
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_layout`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `ptr`
--> src\main.rs:18:30
|
18 | unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
| ^^^ help: if this is intentional, prefix it with an underscore: `_ptr`
warning: unused variable: `layout`
--> src\main.rs:18:44
|
18 | unsafe fn dealloc(&self, ptr: *mut u8, layout: core::alloc::Layout) {
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_layout`
error: linking with `avr-gcc` failed: exit code: 1
|
= note: "avr-gcc" "C:\\Users\\EVANSG~1\\AppData\\Local\\Temp\\rustcmeadZC\\symbols.o" "<2 object files omitted>" "-Wl,--as-needed"
"-Wl,-Bstatic" "C:\\Users\\EvansGrace02\\Documents\\Workspace\\avr_undefined_abort\\target\\avr-none\\release\\deps/{liballoc-9c92b638956aedfc.rlib,librustc_std_workspace_core-1131ff51ed7f00cf.rlib,libcore-1cd83881e403c7a7.rlib,libcompiler_builtins-8c53ab747d5dc2e3.rlib}.rlib" "-L" "C:\\Users\\EVANSG~1\\AppData\\Local\\Temp\\rustcmeadZC\\raw-dylibs" "-Wl,-Bdynamic" "-lgcc" "-Wl,-z,noexecstack" "-o" "C:\\Users\\EvansGrace02\\Documents\\Workspace\\avr_undefined_abort\\target\\avr-none\\release\\deps\\avr_undefined_abort-99f447f01c535b46.elf" "-Wl,--gc-sections" "-no-pie" "-mmcu=atmega328p" "-Wl,--strip-debug" "-nodefaultlibs"
= note: some arguments are omitted. use `--verbose` to show all linker arguments
= note: C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcore-1cd83881e403c7a7.rlib(core-1cd83881e403c7a7.core.d0224d2e180dad47-cgu.02.rcgu.o): In function `core::hint::unreachable_unchecked':␍
core.d0224d2e180dad47-cgu.02:(.text._ZN4core4hint21unreachable_unchecked17hd73c2234e42a966eE+0xa): undefined reference to `abort'␍
C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcore-1cd83881e403c7a7.rlib(core-1cd83881e403c7a7.core.d0224d2e180dad47-cgu.06.rcgu.o): In function `core::num::nonzero::NonZero<T>::new_unchecked':␍
core.d0224d2e180dad47-cgu.06:(.text._ZN4core3num7nonzero16NonZero$LT$T$GT$13new_unchecked17h86576d22dcc7150bE+0x4c): undefined reference to `abort'␍
C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcore-1cd83881e403c7a7.rlib(core-1cd83881e403c7a7.core.d0224d2e180dad47-cgu.06.rcgu.o): In function `core::fmt::FormattingOptions::align':␍
core.d0224d2e180dad47-cgu.06:(.text._ZN4core3fmt17FormattingOptions5align17h25263cf3c1a26f6aE+0x96): undefined reference to `abort'␍
C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcore-1cd83881e403c7a7.rlib(core-1cd83881e403c7a7.core.d0224d2e180dad47-cgu.06.rcgu.o): In function `core::fmt::getcount':␍
core.d0224d2e180dad47-cgu.06:(.text._ZN4core3fmt8getcount17h7ca8f2ef5a49a849E+0x44): undefined reference to `abort'␍
C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcore-1cd83881e403c7a7.rlib(core-1cd83881e403c7a7.core.d0224d2e180dad47-cgu.06.rcgu.o): In function `core::fmt::Formatter::padding':␍
core.d0224d2e180dad47-cgu.06:(.text._ZN4core3fmt9Formatter7padding17h725c8d0e59f6bf75E+0x72): undefined reference to `abort'␍
C:\Users\EvansGrace02\Documents\Workspace\avr_undefined_abort\target\avr-none\release\deps\libcompiler_builtins-8c53ab747d5dc2e3.rlib(compiler_builtins-8c53ab747d5dc2e3.compiler_builtins.404ba4952ab58ac7-cgu.05.rcgu.o):compiler_builtins.404ba4952ab58ac7-cgu.05:(.text._ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$13is_aligned_to17h9342a87594a14351E+0xac): more undefined references to `abort' follow␍
collect2.exe: error: ld returned 1 exit status␍
= note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
= note: use the `-l` flag to specify native libraries to link
= note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
warning: `avr_undefined_abort` (bin "avr_undefined_abort") generated 3 warnings
error: could not compile `avr_undefined_abort` (bin "avr_undefined_abort") due to 1 previous error; 3 warnings emitted
Metadata
Metadata
Assignees
Labels
A-linkageArea: linking into static, shared libraries and binariesArea: linking into static, shared libraries and binariesC-bugCategory: This is a bug.Category: This is a bug.O-AVRTarget: AVR processors (ATtiny, ATmega, etc.)Target: AVR processors (ATtiny, ATmega, etc.)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
EvansJahja commentedon Apr 13, 2025
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
EvansJahja commentedon Apr 13, 2025
The failure disappears when using
opt-level = 1
(or above).opt-level='s'
andopt-level='z'
works.The failure only happens when using
opt-level=0
EvansJahja commentedon Apr 13, 2025
Regardless of
opt-level
, settingbuild-std-features = ["panic_immediate_abort"]
always trigger the ICE.EvansJahja commentedon Apr 13, 2025
Current workaround
EvansJahja commentedon Apr 13, 2025
Update: another example without alloc
https://github.com/EvansJahja/avr_undefined_abort/tree/no_alloc
Changing
panic!("{}", 1);
topanic!("1");
works. I guess it makes sense because panic allocate things, so there's a difference in behavior, but I don't know how this has anything to do with abort.bjorn3 commentedon Apr 13, 2025
I think LLVM lowers trap instructions to calls of the
abort
function on targets that don't have a native trap instruction. https://github.com/llvm/llvm-project/blob/cbe8f3ad7621e402b050e768f400ff0d19c3aedd/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp#L4470EvansJahja commentedon Apr 14, 2025
That makes sense, but I'm under the assumption that avr builds with libgcc which should have the
abort
function..Patryk27 commentedon Apr 19, 2025
Minimized:
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:
... gets compiled into:
... with
ud2
being a "throw invalid opcode exception" instruction.Since AVRs are simpler than your typical x86 processor, they don't have an equivalent of
ud2
, the implementation is left for the user - you might want to print something to serial output, blink LEDs etc., but you need to specify the behavior yourself: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
fn abort()
within compiler-builtins).I'll experiment and report back.
EvansJahja commentedon Apr 19, 2025
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.
abort()
rust-lang/compiler-builtins#830