Jump to content

Stack allocation and stack size

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
3 replies to this topic

#1
mircan

mircan

    Newbie

  • Members
  • Pip
  • 2 posts
Hi

I've got the following question: what detrmines the size of the stack of a process in Linux?
Below are two programs written in C and their disassembly (I know Prog1.c is not the way one should handle with pointers :) ). The assembly codes are very similiar but execution of the first program causes segmentation fault. The initial stack of the first program is about 12 KB while for the second it's about 980 KB. What determines this, if the assembly codes are so similiar?
And even assumming that initial stack of the first program is 12 KB - why writing to address from within the stack limit (about 8 MB on my system) doesn't make the system expand the stack?
Is there any stack allocation at the binary level? Is the stack size determined by the compiler?

Prog1.c:

int main()

{

        char a;        

        char* b = &a;

        b = b - 999999;

        *b = '\0';

}


Prog1.s:

        .file        "prog1.c"

        .text

.globl main

        .type        main, @function

main:

        pushl        %ebp

        movl        %esp, %ebp

        subl        $16, %esp

        leal        -5(%ebp), %eax

        movl        %eax, -4(%ebp)

        subl        $999999, -4(%ebp)

        movl        -4(%ebp), %eax

        movb        $0, (%eax)

        leave

        ret

        .size        main, .-main

        .ident        "GCC: (GNU) 4.4.3"

        .section        .note.GNU-stack,"",@progbits


Prog2.c:

int main()

{

        char a[1000000];

        char* b = &a[0];

        *b = '\0';

}


Prog2.s:

        .file        "prog2.c"

        .text

.globl main

        .type        main, @function

main:

        pushl        %ebp

        movl        %esp, %ebp

        subl        $1000016, %esp

        leal        -1000004(%ebp), %eax

        movl        %eax, -4(%ebp)

        movl        -4(%ebp), %eax

        movb        $0, (%eax)

        leave

        ret

        .size        main, .-main

        .ident        "GCC: (GNU) 4.4.3"

        .section        .note.GNU-stack,"",@progbits



#2
Sysop_fb

Sysop_fb

    Programmer

  • Members
  • PipPipPipPip
  • 160 posts
The programs are completely different.

This one is allocating 1 variable a which is of size char and a pointer to char pointing at a.
Then you move the pointer from a to another address 999999 bytes away in memory. Probably a place in read-only memory or atleast a place where a user-space program shouldn't be writing to.
Prog1.c:
int main()
{
        char a;        
        char* b = &a;
        b = b - 999999;
        *b = '\0';
}

Prog1.s:
        .file        "prog1.c"
        .text
.globl main
        .type        main, @function
main:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $16, %esp
        leal        -5(%ebp), %eax
        movl        %eax, -4(%ebp)
        subl        $999999, -4(%ebp)
        movl        -4(%ebp), %eax
        movb        $0, (%eax)
        leave
        ret
        .size        main, .-main
        .ident        "GCC: (GNU) 4.4.3"
        .section        .note.GNU-stack,"",@progbits


This one allocates 1000000 chars in an char array and a pointer to char b which points at the first char in that char array then it sets the value of a[0] to '\0'
Prog2.c:
int main()
{
        char a[1000000];
        char* b = &a[0];
        *b = '\0';
}

Prog2.s:
        .file        "prog2.c"
        .text
.globl main
        .type        main, @function
main:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $1000016, %esp
        leal        -1000004(%ebp), %eax
        movl        %eax, -4(%ebp)
        movl        -4(%ebp), %eax
        movb        $0, (%eax)
        leave
        ret
        .size        main, .-main
        .ident        "GCC: (GNU) 4.4.3"
        .section        .note.GNU-stack,"",@progbits

"The best optimizer is between your ears" - Michael Abrash
Saying you can optimize a program is like saying you understand how a program works on every level of every facet on a specific machines configuration.

#3
mircan

mircan

    Newbie

  • Members
  • Pip
  • 2 posts
I finally found out that the thing is in a way Linux handles page faults. If a page fault related to an address beetwen stack top and stack limit occurs the kernel checks the value in stack pointer register. On x86 for instance stack size is expanded only if the address is not lower than stack pointer - 32.

#4
Sysop_fb

Sysop_fb

    Programmer

  • Members
  • PipPipPipPip
  • 160 posts
The stack size of the second program is expanded because C likes to put local variables on the stack.
subl        $1000016, %esp

"The best optimizer is between your ears" - Michael Abrash
Saying you can optimize a program is like saying you understand how a program works on every level of every facet on a specific machines configuration.