Monday 28 July 2014

Linux Memory Layout Test through C

If you have gone through any Operating System Course, you would have come across the Memory Layout Diagram of a Process in physical RAM. Below diagram show the layout of a process in the memory:



But, the question is how does these layout actually maps to a program that i have written?
Without an example with an actual running program, this concept seems vague and is pretty hard to visualize. I have written a C program to actually verify this layout in the memory. Here is the C code:


From this source code, let us try to predict where this variables would actually be getting stored in the memory.

We know that command line arguments and environment variable goes to the highest memory available to the process. Therefore, the address for this variables must be greater than any other variable or function address.

Next comes the stack. First function that is called in our program is main function itself which makes a call to func which in turn calls func2. Therefore, main should be at the bottom of the stack followed by func and func2 respectively. Mapping this stack into the memory, as stack grows from high memory to low memory, memory address of local variable of main should be greater than (but should be close to) local variable of func whereas func2's local variable should be having the lowest memory address among the three.

On the other hand, heap start from other side (lower address side) and grows toward stack. Therefore any memory allocated on heap should have address lower than any memory on stack. Our dynamic memory arr2 is allocated after arr1. Therefore, address of arr2 should be greater than arr1, as heap grow toward higher memory side.

Third section is data section which comprises of initialized and uninitialized data. Data section lies just below the heap. Hence, it address must be always less than any memory in heap or above heap. Also, uninitialized data is followed by initialized data. Therefore, address of any uninitialized data must be greater than that of initialized data. This behavior can be seen with the variable g1, g2, g3 and g4.

At last comes the text section which stores the read-only code. These falls at the bottom of the memory allocated to process and must be having address lower than any other section.

Here is the sample output of the program when run at ideone. Click on the link to see the run output at their site itself. I am pasting the same here:


You can verify that this conforms to above discussion. Here is a above memory layout diagram modified for our program:



10 comments:

  1. ab to ye program run kar ke dekhna he pare ga :) khoob mamu khoob

    ReplyDelete
  2. perfect explanation , thank you.

    ReplyDelete
  3. Couldn't find any better explanation of memory layout with such nyc example !!!
    Thnx a ton :)

    ReplyDelete
  4. Awesome work bro ..:) u explained very well !

    ReplyDelete
  5. Nice explanation but i have a doubt.
    if func2 have
    static int a=4;
    where it will be saved.

    ReplyDelete
    Replies
    1. It will stored in the initialized data segment.

      Delete
  6. where is volatile , register,and extern is saved.

    ReplyDelete
  7. Very well explained for creating a basic understanding. You could also mention about registers and how sometimes int, char or loop variables are stored in register for faster access due lack of CPU cycles.

    ReplyDelete
  8. Can anyone tell why Stack segment is needed. I mean memory manager can have intelligence to know memory allocated to function calls and dynamically allopcated memory without having seperate sections for stack and heap.

    ReplyDelete