sprintf() heap usage

Vasili Galka vvv444@gmail.com
Tue Jul 16 14:32:00 GMT 2013


Hi Jens,

You are partially correct. On hardware architectures that include MMU
(Memory Management Unit) which enables virtual address space - stack
is usually mapped into separate memory region to trigger page fault
when overflows (as you described).
But on systems without MMU there is no simple way to prevent
Heap-Stack collision.
The collision check implemented in sbrk() that Sandeep showed does not
provide 100% fault-tolerance. It prevents allocating heap memory to
clash the stack, it doesn't prevent stack to grow into the heap and
cause memory corruption.

Best regards,
Vasili

On Tue, Jul 16, 2013 at 5:23 PM, Jens Nyberg <jens.nyberg@gmail.com> wrote:
> I think that is fishy. Isnt the stack mapped in some totally different area
> where if grows too big it would cause a page fault? That is how i would have
> designed it anyway but i didnt write linux so i dont know how they did.
>
> Den 16 jul 2013 16:10 skrev "Sandeep Kumar Singh"
> <Sandeep.Singh2@kpitcummins.com>:
>
>> Hi Vasili,
>>
>> As per my knowledge, heap always take the space at the end of RAM after
>> the
>> other sections. The area assigned to RAM in linker script will be used by
>> .data
>> and .bss sections. The rest of RAM will be used by the stack and heap
>> sections.
>>
>> As the amount of area used by stack and heap will depend on the test-case;
>> they
>> won't be specified in linker script and hence can use the entire area of
>> RAM.
>>
>> The stack and heap size are not fixed. The stack grows downwards towards
>> the
>> heap space, and the heap grows upwards towards the stack. If the stack
>> space
>> grows beyond its boundary and occupies the heap space then the error
>> condition
>> is called stack-heap Collision Error.
>>
>> Heap and stack collision is detected in "sbrk" function which is invoked
>> by
>> "malloc", internally. This function expects that heap area is always
>> between
>> "bss" and "stack" sections.
>>
>> You can also check this is the definition of "sbrk" function.
>> ===============================================================
>> #include <_ansi.h>
>> #include <sys/types.h>
>>
>> register char *stack_ptr asm ("sp");
>> caddr_t sbrk(int incr)
>> {
>> extern char end;         /* Defined by the linker */
>> static char *heap_end;
>> char *prev_heap_end;
>>
>> if (heap_end == 0)
>> {
>> heap_end = &end;
>> }
>> prev_heap_end = heap_end;
>> if (heap_end + incr > stack_ptr)
>> {
>> //printf("Heap and Stack Collision occured\n\r");
>> return (caddr_t)NULL;
>> }
>> heap_end += incr;
>> return (caddr_t)prev_heap_end;
>> }
>> ===============================================================
>>
>> The condition "if (heap_end + incr > stack_ptr)" detects the heap and
>> stack
>> collision. We can also change these boundaries as per our requirement.
>>
>>
>> Regards,
>> Sandeep Kumar Singh,
>> KPIT Cummins InfoSystems Ltd.
>> Pune, India
>>
>>
>>
>> > -----Original Message-----
>> > From: newlib-owner@sourceware.org [mailto:newlib-owner@sourceware.org]
>> > On Behalf Of Vasili Galka
>> > Sent: Tuesday, July 16, 2013 3:09 PM
>> > To: newlib@sourceware.org
>> > Subject: sprintf() heap usage
>> >
>> > Hi,
>> >
>> > I've been surprised to discover that using sprintf() leads to
>> > requirement of sbrk(). Can anyone please explain me why?
>> > For gods sake, the function already has output buffer provided. The
>> > lifetime of the function is well defined and it has stack. Why would
>> > it require heap!?
>> >
>> > Best,
>> > Vasili Galka
>>
>>
>



More information about the Newlib mailing list