Skip to content

Panic on free() if initial heap was not aligned #121

@jannic

Description

@jannic

While debugging #119, I saw some other panics that looked like a different issue and that were not fixed by #120.

When the initial allocation used for the pool is not 32-byte aligned, free() panics:

thread 'main' (54590) panicked at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rlsf-0.2.1/src/tlsf.rs:1545:17:
attempt to subtract with overflow
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/9b1f8ff42d110b0ca138116745be921df5dc97e7/library/std/src/panicking.rs:689:5
   1: core::panicking::panic_fmt
             at /rustc/9b1f8ff42d110b0ca138116745be921df5dc97e7/library/core/src/panicking.rs:80:14
   2: core::panicking::panic_const::panic_const_sub_overflow
             at /rustc/9b1f8ff42d110b0ca138116745be921df5dc97e7/library/core/src/panicking.rs:175:17
   3: rlsf::tlsf::Tlsf<FLBitmap,SLBitmap,_,_>::iter_blocks::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rlsf-0.2.1/src/tlsf.rs:1545:17
   4: <core::iter::sources::from_fn::FromFn<F> as core::iter::traits::iterator::Iterator>::next
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/sources/from_fn.rs:71:9
   5: core::iter::traits::iterator::Iterator::fold
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2609:34
   6: <core::iter::adapters::filter::Filter<I,P> as core::iter::traits::iterator::Iterator>::fold
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/filter.rs:165:19
   7: <core::iter::adapters::filter::Filter<I,P> as core::iter::traits::iterator::Iterator>::fold
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/filter.rs:165:19
   8: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:128:19
   9: <usize as core::iter::traits::accum::Sum>::sum
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/accum.rs:50:22
  10: core::iter::traits::iterator::Iterator::sum
             at /home/jan/.rustup/toolchains/beta-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3599:9
  11: embedded_alloc::tlsf::Heap::free_with_cs
             at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embedded-alloc-0.7.0/src/tlsf.rs:126:18
  12: embedded_alloc::tlsf::Heap::free::{{closure}}
             at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embedded-alloc-0.7.0/src/tlsf.rs:110:42
  13: critical_section::with
             at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/critical-section-1.2.0/src/lib.rs:248:14
  14: embedded_alloc::tlsf::Heap::free
             at /home/jan/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embedded-alloc-0.7.0/src/tlsf.rs:110:9
  15: embedded_alloc_test::main
             at ./src/main.rs:26:31

Code leading to this panic:

use std::mem::MaybeUninit;

use embedded_alloc::TlsfHeap;


fn main() {
    let local_heap: TlsfHeap = TlsfHeap::empty();

    // For values 0<MISALIGN<32, free() panics
    const MISALIGN: usize = 16;

    // The usable size should not shrink due to misalignment, so grow the allocation accordingly
    const HEAP_SIZE: usize = 256+MISALIGN;

    // The overall allocation should be aligned
    #[repr(align(32))]
    struct Wrapper([MaybeUninit<u8>; HEAP_SIZE]);
    let mut heap_mem = Wrapper([MaybeUninit::uninit(); HEAP_SIZE]);

    let addr = heap_mem.0.as_mut_ptr() as usize + MISALIGN;
    let size = HEAP_SIZE - MISALIGN;

    println!("{:x} {:x}", addr, size);
    unsafe { local_heap.init(addr, size) }

    println!("{}", local_heap.free());
}

Full repo reproducing the issue: https://github.com/jannic/embedded-alloc-test

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions