You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The reproducer is available ready-to-go at https://codeberg.org/mei-b/farbix, commit 26684d7b9339112b9b4fc08ca7c0d973341ce929. The code itself is as follows:
#![no_std]#![no_main]use arduino_hal::{Peripherals, port};
panic_serial::impl_panic_handler!(
arduino_hal::usart::Usart<
arduino_hal::pac::USART0,
port::Pin<port::mode::Input, arduino_hal::hal::port::PE0>,
port::Pin<port::mode::Output, arduino_hal::hal::port::PE1>
>
);#[inline(never)]fnmeow1(){meow2()}#[inline(never)]fnmeow2(){panic!("{}",2137)}#[arduino_hal::entry]fnmain() -> ! {let dp = Peripherals::take().unwrap();let pins = arduino_hal::pins!(dp);let serial = arduino_hal::default_serial!(dp, pins,57600);let serial = share_serial_port_with_panic(serial);meow1();// if bug doesn't reproduce on a newer compiler, try calling// meow2 directly insteadloop{}}
I compile this with the following settings in .cargo/config.toml:
[package]
name = "farbix"version = "0.1.0"edition = "2024"
[dependencies]
[dependencies.arduino-hal]
git = "https://github.com/Rahix/avr-hal"features = ["arduino-mega2560"]
# main branch at the time of writingrev = "6de651a2303ad1f392fc628675af2372632df4fb"
[dependencies.panic-serial]
git = "https://github.com/nilclass/panic-serial"rev = "409d81c6f5d36d2fc73e4df0e0b0a09e10989b94"# PR #1features = ["full"]
[profile.release]
panic = "abort"lto = trueopt-level = "s"
Note that these particular dependencies aren't central to the issue – it's just the easiest way I knew of for creating a self-contained example for what's inherently bare-metal target.
To run this example without physical hardware, clone and compile https://github.com/buserror/simavr, and then run something along the lines of:
Panic at src/main.rs:21:5: �./home/mei/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/num.rs...
Panic at ........"...Y.......................C.�.00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899called
`Option::unwrap()` on a `None` valueE.n.^[garbage continues]
The breakage bisects to #148789. Moreover, the issue only occurs on the atmega2560, and doesn't reproduce on e.g. the atmega1280. The bug occurs because:
the flash memory of the ATmega2560 is big enough that a 16-bit program counter is not enough. Because of this, the return addresses on the stack are 3 bytes long:
Compare Section 7.6 "Stack Pointer" of the ATmega640/V-1280/V-1281/V-2560/V-2561/V datasheet
The Stack Pointer is decremented by one when data is pushed onto the Stack with the PUSH instruction, and it is decremented by two for ATmega640/1280/1281 and three for ATmega2560/2561 when the return address is pushed onto the Stack with subroutine call or interrupt.
on AVR, LLVM ignores any alignment requirements passed to alloca, and the generated code never concerns itself with stack alignment
normally, this is fine, because the AVR instruction set doesn't have any instructions that would care about the alignment of memory addresses
because the Arguments are allocated on the stack, a misaligned pointer is embedded in the fmt::Arguments, which then gets interpreted as the string literal case – printing kilobytes of garbage onto the serial port
The reproducer is available ready-to-go at https://codeberg.org/mei-b/farbix, commit
26684d7b9339112b9b4fc08ca7c0d973341ce929. The code itself is as follows:I compile this with the following settings in
.cargo/config.toml:The dependencies involved are as follows:
Note that these particular dependencies aren't central to the issue – it's just the easiest way I knew of for creating a self-contained example for what's inherently bare-metal target.
To run this example without physical hardware, clone and compile https://github.com/buserror/simavr, and then run something along the lines of:
Expected result:
Actual result:
Meta
rustc --version --verbose:Diagnosis
The breakage bisects to #148789. Moreover, the issue only occurs on the
atmega2560, and doesn't reproduce on e.g. theatmega1280. The bug occurs because:alloca, and the generated code never concerns itself with stack alignmentcore::fmt::rt::Argumentas a tag.Arguments are allocated on the stack, a misaligned pointer is embedded in thefmt::Arguments, which then gets interpreted as the string literal case – printing kilobytes of garbage onto the serial port