rust-embedded/rust-raspberrypi-OS-tutorials · error
Overflow on Address::sub
Error message
Overflow on Address::sub
What it means
This panic is thrown by the Sub<usize> implementation for Address<ATYPE> when the checked subtraction of a usize offset from the address's underlying value underflows (result would be negative). The kernel wraps addresses in a typed Address struct and refuses to silently wrap on arithmetic overflow, so any pointer arithmetic that goes below zero panics instead. It exists to catch pointer-bug errors early in kernel code rather than corrupting memory.
Source
Thrown at 20_timer_callbacks/kernel/src/memory.rs:105
impl<ATYPE: AddressType> Add<usize> for Address<ATYPE> {
type Output = Self;
#[inline(always)]
fn add(self, rhs: usize) -> Self::Output {
match self.value.checked_add(rhs) {
None => panic!("Overflow on Address::add"),
Some(x) => Self::new(x),
}
}
}
impl<ATYPE: AddressType> Sub<usize> for Address<ATYPE> {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: usize) -> Self::Output {
match self.value.checked_sub(rhs) {
None => panic!("Overflow on Address::sub"),
Some(x) => Self::new(x),
}
}
}
impl<ATYPE: AddressType> Sub<Address<ATYPE>> for Address<ATYPE> {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: Address<ATYPE>) -> Self::Output {
match self.value.checked_sub(rhs.value) {
None => panic!("Overflow on Address::sub"),
Some(x) => Self::new(x),
}
}
}
impl Address<Virtual> {View on GitHub (pinned to 644474cc09)
Solutions
- Audit the subtraction site and clamp/branch: only subtract when `address_value >= offset`, otherwise return None/stop the loop.
- Compute from the correct base — subtract from the region end address, not the start.
- Check for usize underflow from a negative value: verify the offset is not produced by casting a negative isize.
- Replace the expression with checked arithmetic yourself (`checked_sub`) so you can handle the underflow case gracefully.
- Add an assertion/log of the address and offset before the subtraction to identify the bad input.
Example fix
// before
let base = region_start - size;
// after
let base = region_start.checked_sub(size)
.ok_or("region start below heap base")?; Defensive patterns
Strategy: validation
Validate before calling
fn safe_sub_usize(addr_value: usize, rhs: usize) -> Option<usize> {
addr_value.checked_sub(rhs)
} Type guard
fn can_sub(addr_value: usize, rhs: usize) -> bool {
addr_value >= rhs
} Try / catch
// Rust panics are not catchable here (no_std kernel); validate before:
match addr.value.checked_sub(rhs) {
Some(x) => Address::new(x),
None => { /* handle underflow: stop loop / return error */ }
} Prevention
- Always bound downward loops with an inclusive condition (e.g. `while addr > base`).
- Never cast negative numbers to usize before subtracting.
- Compute sizes from end - start, not offsets from start.
- Prefer checked_sub at call sites when underflow is plausible.
When it happens
Trigger: Calling `address - n` (or `*ptr.offset(-n)` style arithmetic via `-`) where n is larger than the address value, e.g. subtracting a size from the start of a virtual region, iterating downward past the base address, or passing a wrong/negative-derived offset.
Common situations: Downward loops over a memory region that run one iteration past the region start; subtracting a region size from the region start instead of the end; sign confusion where a usize cast of a negative number becomes huge; off-by-one in bounds computations for stack or heap layout.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Overflow on Address::add
- Allocation error: {:?}
- Invalid KERNEL_STATE
- transition_to_single_core_main() called while state != Init
- Attempt to enable IRQ {} for device {}, but driver does not
AI-assisted analysis of rust-embedded/rust-raspberrypi-OS-tutorials@644474cc09 (2026-09-06).
Data as JSON: /api/errors/439bc35af3c67200.
Report an issue: GitHub.