[heap_4.c] data access violation when inserting the block with the highest memory address into the free list

mcinnis wrote on Monday, March 26, 2018:

Hi,

I hit a problem of data access violation when inserting a block whoms address is the highest in the memory. The following interation of current free list will go to the end of block with the condition, pxIterator->pxNextFreeBlock = NULL, and then the next iteration will trigger illegal memory access, NULL->pxNextFreeBlock.

	/* Iterate through the list until a block is found that has a higher address
	than the block being inserted. */
	for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
	{
		/* Nothing to do here, just iterate to the right position. */
	}

I tried to fix it with following snippet of code, and it works.

--- a/kernel/FreeRTOS/Source/portable/MemMang/heap_4.c
+++ b/kernel/FreeRTOS/Source/portable/MemMang/heap_4.c
@@ -443,7 +443,9 @@ uint8_t *puc;
        than the block being inserted. */
        for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
        {
-               /* Nothing to do here, just iterate to the right position. */
+               /* pxIterator is the block with highest address in the free list */
+               if(pxIterator->pxNextFreeBlock == NULL)
+                       break;
        }

        /* Do the block being inserted, and the block it is being inserted after
@@ -462,7 +464,8 @@ uint8_t *puc;
        /* Do the block being inserted, and the block it is being inserted before
        make a contiguous block of memory? */
        puc = ( uint8_t * ) pxBlockToInsert;
-       if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
+       if( pxIterator->pxNextFreeBlock && /* if NULL, there is no block being inserted before */
+               ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
        {
                if( pxIterator->pxNextFreeBlock != pxEnd )
                {

Could anyone help to double confirm this?

rtel wrote on Monday, March 26, 2018:

I would be grateful if you can provide more information to enable us to
try and replicate the issue you are seeing. In particular, what do you
mean by “inserting a block whoms address is the highest in the memory”?
How can I replicate that?

For example, if all my heap is free, then I call pvPortMalloc() three
times, each time to obtain one third of the available heap memory, the
memory returned to me the lowest one third of the heap for the first
pvPortMalloc() call, the middle third for the second pvPortMalloc()
call, and the top third for the third pvPortMalloc() call. After this,
is calling vPortFree() to return the highest of those three blocks what
you mean by “inserting a block whose address is the highest in the memory”?

Hi
I’m not sure if this fix relates to my problem i’ve seeing.

My pxBlockToInsert->pxNextFreeBlock is NULL and so it’s stuck there

The Starting address of the heap is 0x20019094 and i got 120000bytes so that goes up to 0x20036554.

pxBlockToInsert is at 0x2002C428
pxIterator is at 0x2002C400

so it does not seem to be at end as the first post saying indends to fix.
xPortGetFreeHeapSize was called few ms before and gives 36k back.

i now try to hack those fixes in and check if it helps.
May someone look at it, and fix it in the code, since this is still in there…

Cheers