Forum Discussion

UnixDev's avatar
UnixDev
Icon for New Contributor rankNew Contributor
1 month ago

eCoS OS throws execption when freeing memory

We have a firmware applicaiton that makes use of eCoS RtoS and NIOSII core. We have a logic that we first allocate memory dynamically and then if required delete the previous allocated memory and allocate bigger one - this step goes on until requirement is met. But we are observing exception from eCos during execution of these steps - in other words say when we ietrate over the above logic for 7th time, while freeing memory that time we get exception but allocation which is done prior to free succeeds:

ExceptionHandler(data = 0x0, exception_number = 0x0, info = 0x017FFF74)
cyg_hal_exception_handler(regs = ???)
_software_exception_handler(asm)
exception
Cyg_Mempool_dlmalloc_Implementation::free(this = 0x0158AD40, mem = ???, unnamed = ???)
Cyg_Mempolt2<Cyg_Mempool_dlmalloc_Implementation>::free(this = 0x0158AD40, p = ???, size = ???)
free(ptr = ???)
npfree(ptr = 0x017136A0)
vf_free_buffer(buffer = 0x017136A0, size = 0x0007E000)
vfwrite_locked(buf = 0x016956B0, size = 0x1, items = 0x0400, vfd = 0x01696F10)
vfwrite(buf = 0x016956B0, size = 0x1, items = 0x0400, vfd = 0x01696F10)
getfile(asm)
WriteFileToFlash(notUsed = 0x0)
ecos_thread_entry(entry = 0x0D)
Cyg_Scheduler_Base::get_current_thread(inline)
Cyg_Thread::self(inline)
Cyg_Thread::exit(inline)
Cyg_HardwareThread::thread_entry(thread = 0x01262448)
end of frame

Can anyone please let me know why exception is thrown at later part of step process execution and what the fix for this issue?

1 Reply

  • Sparrow_Altera's avatar
    Sparrow_Altera
    Icon for Occasional Contributor rankOccasional Contributor

    You may have a possible heap corruption based on the stack trace. The fact that the allocation just before this succeeds, but free dies, fits with heap corruption: malloc didn’t happen to touch the damaged area; free did. Heap metadata is corrupted or the pointer/size you’re freeing is not consistent with how it was allocated.

    Things you can check:

    1. Size mismatch between alloc and free: Confirm that the size used for allocation and the size passed into vf_free_buffer() are always identical.
    2. Buffer overrun/underrun before the 7th free: If bytes_to_copy exceeds either the old or new allocation size, you write -> That trashes the allocator’s metadata. dlmalloc stores control info just before/after the user block; once that’s corrupted, the next free() can blow up. Check all memcpy, memmove, memset, and loops that touch this buffer.
    3. Double free or freeing a modified pointer: After vf_free_buffer(), always set the pointer to NULL. Make sure there’s a single owner of this buffer; no multiple modules freeing it.
    4. Using the buffer after freeing: If your “resize until bigger” logic lives in this area, it’s easy to do: Allocate buffer, Use buffer, Decide you need a bigger buffer → allocate new, free old. But something still holds a pointer to the old buffer and writes into it while or after it’s freed. This again corrupts heap metadata, shows up in a later free(). Ensure that all users of the buffer go through a single handle. Whenever you resize, update that handle everywhere before any further writes.
    5. Memory layout / stack overlap: If stack or some other buffer overwrites the heap region around 0x017136A0, dlmalloc will die on free.

    As a sanity check: Temporarily skip resizing logic

    • Change the code to allocate a large enough buffer once, then use it without freeing/resizing in the loop.
    • Keep all the same write/copy logic.

    If the exception disappears:

    • The problem is very likely tied to how you’re managing allocations (size mismatch/double free).

    If the exception still occurs:

    • The bug is almost certainly a pure buffer overrun/underrun in your write logic, independent of malloc/free.