[En-Nut-Discussion] NutHeapAlloc Error?

Timothy M. De Baillie debaillie at ciholas.com
Tue Oct 14 23:26:08 CEST 2008


Timothy M. De Baillie wrote:
> Timothy M. De Baillie wrote:
>   
>> Nathan Moore wrote:
>>   
>>     
>>> On Mon, Oct 13, 2008 at 3:06 PM, Timothy M. De Baillie <
>>> debaillie at ciholas.com> wrote:
>>>
>>>   
>>>     
>>>       
>>>> I'm trying to trace down a bug on a system that has REALLY low memory
>>>> and has lots and lots of mallocs.  So this may not really be a problem,
>>>> but I thought I would see what others thought.
>>>>
>>>> in the OS, os/heap.c,
>>>>
>>>> ~~~ OS CUT ~~~
>>>> void *NutHeapAlloc(size_t size)
>>>> {
>>>>
>>>> ......
>>>>
>>>>    if (size >= available) {
>>>> #ifdef NUTDEBUG
>>>>        if (__heap_trf)
>>>>            fputs("MEMOVR\n", __heap_trs);
>>>> #endif
>>>>        return 0;
>>>>    }
>>>>
>>>>    /*
>>>>     * We need additional space in front of the allocated memory
>>>>     * block to store its size. If this is still less than the
>>>>     * space required by a free node, increase it.
>>>>     */
>>>>    if ((size += MEMOVHD) < sizeof(HEAPNODE))
>>>>        size = sizeof(HEAPNODE);
>>>> ~~~ OS CUT ~~~
>>>>
>>>> Should the check "if(size >= available)" not happen after the last two
>>>> lines?
>>>>
>>>>  From what I read, if you request 11 bytes and had exactly 11 bytes
>>>> available, then you would cause a memory wrap of some sort.
>>>>
>>>>     
>>>>       
>>>>         
>>> I think it would result in similar behavior as if you had 100 bytes free in
>>> 10 byte chunks and requested 20 bytes.
>>> You'd check each of the chunks, none of them would be big enough, and in the
>>> end (when (0== (node = node->next))
>>> you'd break out of the loop.
>>> It would behave correctly, as far as I can tell, but since the available
>>> test is done anyway it might as well be done after
>>> the size adjustments.
>>>
>>> Nathan
>>> _______________________________________________
>>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>>
>>>   
>>>     
>>>       
>> Ok, so we made this change and we are still having malloc issues. 
>> However, we have traced it down to one specific line in os/heap.c:
>>
>> *fpp = fit->hn_next;
>>
>> in the else of:
>>
>> if (fit->hn_size > size + sizeof(HEAPNODE) + ALLOC_THRESHOLD) {
>>
>> The system "locks up" or jumps to abort if you attempt to set *fpp to 
>> NULL. So this happens if your "fit" is the last heap in the heap list 
>> and you can't split it. I don't understand how setting a pointer to NULL 
>> causes the ARM to abort, but it does.
>>
>> Why would setting *fpp to NULL cause a lockup and how do we resolve this 
>> bug?
>>
>> Thanks in advanced,
>>
>> Tim
>>
>> _______________________________________________
>> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>>
>>   
>>     
> OK, this is 100% repeatable. If the "fit" heap is chosen and is the last 
> heap section, it WILL fail on this instruction. Here is some code that 
> WILL exercise this.
>
> ~~~begin code~~~
> FILE *uart;
>
> unsigned long uart_baud = 115200;
>
> void main(){
>
> //initialize your uart to allow to see if things are still working when 
> we complete
> NutRegisterDevice(&DEV_UART, 0, 0);
> uart = fopen(DEV_UART_NAME, "r+");
> _ioctl(_fileno(uart), UART_SETSPEED, &uart_baud);
> outr(AIC_SMR(US0_ID), 0x04);
>
> fputs("\r\nWelcome to the test.", uart);
> NutSleep(3000); //allow serial to go out
> fputs("\r\nHere goes the test\r\n.", uart);
> NutSleep(30); //allow serial to go out
>
> //malloc all but a one less than the amount needed to split
> malloc(NutHeapAvailable()-sizeof(HEAPNODE)-ALLOC_THRESHOLD+1); //this 
> will malloc all the space except just enough to NOT split the left over 
> space
>
> //now report if we are working
> fputs("\r\nIt didn't fail!!\r\n", uart);
>
> for(;;){
> NutSleep(1000);
> }
> }
> ~~~end code~~~
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion
>
>   
We found the error. Solution coming out soon..


Tim



More information about the En-Nut-Discussion mailing list