AnsweredAssumed Answered

Bug in EWL malloc?

Question asked by Alex Stefan on May 19, 2014
Latest reply on Jun 3, 2014 by Alex Stefan

Hello!

 

I've been working for a few months on a bare-metal Kinetis project, using Processor Expert to provide the HAL. I'm using CW MCU 10.5.

 

What initially appeared to be a bug in my own code (four bytes being assigned random values in the middle of a buffer), actually translated into what looks to me as a bug in the malloc() routine.

 

/* Second: couldn't find a buffer that would fit. attempt to merge two     existing buffers to make do. */       /* nbytes cannot fit into struct m_buff -> size */     if ( MAX_M_BUFF < nbytes ) {         return NULL;     }       p = head;     while ( NULL != p ) {         if ( NO == p->used ) {             struct m_buff* look_ahd = p->lnk;             size_t tot_room = p->size;               while ((NULL != look_ahd) && (NO == look_ahd->used) && (tot_room < nbytes)) {                 tot_room += ((size_t)look_ahd->size + sizeof(struct m_buff));                 look_ahd = look_ahd->lnk;             }               if ( tot_room >= nbytes ) {                 LOCALALLOC(p, nbytes)                 p->lnk = look_ahd;                 p->used = YES;                 p->size = tot_room;                 #if HEAP_GROWS                 if ((look_ahd != NULL) && (look_ahd->lnk == NULL))                     tail = &p->lnk;                                 #endif                   #if defined(_REENTRANT) && _REENTRANT                 __end_critical_region ( malloc_pool_access );                 #endif                 return ((char_t*) p ) + sizeof( struct m_buff );             }         }         p = p->lnk;     }

 

 

Basically, if multiple free buffers are merged to satisfy the need for a bigger buffer, the tail will keep pointing to where an old 'buffer' used to be. The effect of this is that, when a new buffer is allocated using sbrk(),

 

#if HEAP_GROWS     *tail = new_buff;     new_buff->lnk = NULL;     tail = &new_buff->lnk;      #else

 

the instruction at line 2 will write the address of the new buffer right in the middle of a previously allocated area.

 

This is the current sequence of mallocs/free, I will try to narrow it down to a simpler test-case tomorrow:

a = malloc(8);

b = malloc(16);

free(a);

free(b);

a = malloc(1140);

b = malloc(16);

free(a);

free(b);

a = malloc(200);

b = malloc(16);

free(a);

free(b);

a = malloc(8);

b = malloc(16);

free(a);

free(b);

a = malloc(1140);

b = malloc(16); -> This is when 'tail' overwrites bytes in the middle of my buffer.

 

Wondering if this is something that the development team is aware of and if they have a fix.

 

Thanks,

Alex

Outcomes