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: sprintf() heap usage


Dear Jens,

Why do you see it as over generalization? For instance, I'm currently
developing application that uses newlib in an embedded solution without any OS.
Besides, you still can find plenty of architectures without MMUs...
Pretty much any weak embedded CPU. Would you say using standard C
library on such architectures is an outrageous request?

In any case, this has nothing to do with the initial point of this thread.

Best,
Vasili


On Tue, Jul 16, 2013 at 5:56 PM, Jens Nyberg <jens.nyberg@gmail.com> wrote:
> Well if we are gonna generalize that much now when we speak about some os
> besides linux running on an arch without mmu support. What says the stack if
> it collides will always collide with the heap of the same process? I guess
> that must be a precondition for newlib.
>
> Den 16 jul 2013 16:32 skrev "Vasili Galka" <vvv444@gmail.com>:
>
>> 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
>> >>
>> >>
>> >


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