This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Strange malloc() problem, what am I missing


* Per-Henrik Lundblom <ph@whatever.nu> [060810 09:50]:

> Hi,
> 
> I'm using newlib in a project involving FreeRTOS running on an ARM7
> target (Philips LPC2138, 32kb RAM). I have use pre-compiled GnuARM
> toolchain available from www.gnuarm.net running on both Windows and 
> Linux. The newlib version is 1.14.0.
> 
> I have spent the last week trying to sort out a strange problem that
> occurs when using malloc() (eg. malloc_r()). In my application I alloc a
> few "large" blocks (~1kb) and then continously alloc and free a lot of
> small chunks (8-100bytes). I haven't fully understood exactly how the
> malloc implementation in newlib works but I will try to describe the
> problem:
> 
> Eventually a 24 bytes allocated chunk will be free:d and placed in the
> 24 bytes bin. This is the only chunk in the 24 bytes bin so the two
> next/prev chunk pointers in the chunk points to the same location and
> that location is the chunk itself.
> 
> This chunk eventually is allocated with a malloc(18) which turns out to
> a request to a 24 bytes chunk. The code executed is mallocr.c:2357.
> victim and q is set and are not equal so the code block starting at line 
> 2374 is executed. The unlink() macro is executed. Here I experience the
> strange problem. Unlink doesn't release the chunk from the 24 byte bin
> in the __malloc_av_ (av_ in mallocr.c). Because the chunk is the only
> chunk in the 24 byte bin I get the impression it should!
> 
> Anyway, the chunk is allocated and returned to the application that
> writes data to it. The next/prev pointers that where in the "head" of
> the chunk when it was free is of course overwritten because this memory
> is allocated and returned to the application.
> 
> After a while a malloc(8) is requested. This is again seen as a small 
> request by malloc. The code in the block mallocr.c:2357 is executed. q and
> victim is set, but because these are equal, the q and victim is advanced
> one bin. But now this bin is still pointing at the chunk that where
> allocated to the application previously! The application has overwritten
> the next/prev pointers in the chunk and because of this, these pointers
> are invalid and results in a data abort on the ARM7 when executing the
> unlink() macro.
> 
> I have fixed this with a simple if statement checking if all the
> conditions mentioned above is true. If yes, the __malloc_av_ bin array
> is updated. See patch below.
> 
> THE REAL QUESTION IS: What am I missing, have I mis-configured
> something? I can't really see such a simple thing beeing a flaw in the
> implementation.
> 
> --- newlib-1.14.0/newlib/libc/stdlib/mallocr.c  2005-10-07 20:07:26.000000000 +0200
> +++ newlib-1.14.0_patched/newlib/libc/stdlib/mallocr.c  2006-08-09 17:07:14.4230 64700 +0200
> @@ -2367,6 +2367,7 @@ Void_t* mALLOc(RARG bytes) RDECL size_t
>      if (victim == q)
>      {
>        q = next_bin(q);
> +      victim = (mchunkptr) q;
>        victim = last(q);
>      }
>  #endif
> @@ -2374,6 +2375,11 @@ Void_t* mALLOc(RARG bytes) RDECL size_t
>      {
>        victim_size = chunksize(victim);
>        unlink(victim, bck, fwd);
> +if (victim->fd == victim->bk && last(q) == first(q) && victim->fd ==
> last(q))
> +{
> +    q->fd = q;
> +    q->bk = q;
> +}
>        set_inuse_bit_at_offset(victim, victim_size);
>        check_malloced_chunk(victim, nb);
>        MALLOC_UNLOCK;
> 

Doesn't anyone have a clue about this? 

/PH

--
Per-Henrik Lundblom           epost: ph@whatever.nu
telefon: 0733-20 71 26        hemsida: www.whatever.nu


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]