Virtual Memory. Stack

Tasks

Rulați make pentru a compila sursele din directorul session-02-tasks.

Memoria Virtuală. Spațiul de adresă

  1. Formatul ELF
    • Folosiți utilitarul readelf pentru a afisa informații despre secțiunile executabilului adr_space. (Hint: man readelf, search: sections)
    • Identificați secțiunile .text, .rodata, .data și .bss. Observați diferențele în coloana Type între .bss și .data. Ce înseamnă ele?
  2. Secțiunile unui executabil
    • Urmăriți declarațiile de variabile din fișierul adr_space.c. Determinați secțiunea în care a fost plasată fiecare variabilă. În acest scop folosiți objdump. (Hint: objdump -t)
    • Verificați că dimensiunea fiecărei variabile (a 5-a coloană din output-ul lui objdump) corespunde cu declarația corespunzătoare din fișierul adr_space.c.
    • De ce dimensiunea lui string2 este doar 4? Folosiți readelf pentru a afișa tot conținutul secțiunii .data (Hint: readelf -x). De ce lipsește conținutul variabilei string2?
    • Folosiți readelf pentru a căuta secțiunea în care este conținutul variabilei string2. Cum explicați?
  3. Layout-ul procesului în memorie
    • Rulați executabilul adr_space. Folosiți pmap pentru a afișa zonele de memorie mapate. Câte din zonele afișate de pmap sunt asociate executabilului adr_space? Identificați stiva și heap-ul.
    • Ne propunem să determinăm pentru fiecare din secțiunile .text, .rodata, .data și .bss în ce zonă de memorie au fost încărcate. Folosiți coloana Addr din output-ul lui readelf de la punctul 1 pentru a asocia fiecare din aceste secțiuni într-o zonă de memorie din cele afișate de pmap.
    • Cum a știut sistemul de operare să creeze cele 3 zone de memorie?
      • Secțiunile conțin doar informații “statice”, care ne ajută să ne organizăm mai bine executabilul. Când un executabil este rulat, însă, se folosesc alte informații din fișierul ELF pentru a stabili ce zone de memorie se creează. Aceste informații se numesc “Program headers” sau “Segmente”.
      • Afișați segmentele din fișierul adr_space, folosind readelf. Doar segmentele marcate cu “LOAD” vor fi încărcate în memorie. Corespund adresele acestor segmente cu output-ul lui pmap?

Stiva

  1. Rulați programul return_array. De ce nu funcționează? Corectați programul astfel încât să funcționeze corect.
  2. Rulați programul params. Cum explicați comportamentul?
  3. Rulați programul stackframe. Programul realizează apelurile de funcții mainfg. Funcția g afișează conținutul stivei. Identificați frame-urile corespunzătoare funcțiilor main, f și g. Care sunt adresele de return? Folosiți utilitarul addr2line pentru a verifica faptul că adresa de return este într-adevăr imediat după apelul funcției.

GDB

  1. Rulați programul bug. Vom folosi GDB pentru a identifica motivul erorii.
gdb ./bug
(gdb) run

Programul se va opri la linia care a cauzat accesul invalid. Pentru a afișa valorile variabilelor folosim comanda print.

După ce am identificat ce variabilă are o valoare nevalidă vrem să aflăm motivul pentru care a ajuns așa. Folosiți comanda backtrace pentru a afișa stiva de apeluri.

(gdb) backtrace
#0  0x0804846a in initialize (entries=0x0, num=5) at bug.c:15
#1  0x080484c5 in allocate (n=5) at bug.c:31
#2  0x080484df in main () at bug.c:41

Folosiți comanda frame pentru a vă muta în cadrul unui alt frame din stiva de apeluri

(gdb) frame 1
#1  0x080484c5 in allocate (n=5) at bug.c:31
31		initialize(w, n);

Verificați valorile cu care a fost apelată funcția initialize. De unde provin aceste valori? Folosiți comanda list pentru a afișa codul sursă din jurul liniei curente. Investigați celelalte variabile din funcție și identificați sursa problemei.

Fun

  1. Sunt informațiile despre secțiuni absolut necesare? Analizați programul elf_magic. Câte secțiuni conține programul? Câte segmente conține programul? Credeți că programul va rula?
chmod +x elf_magic
./elf_magic
sesiuni/memory/2.txt · Last modified: 2013/07/09 16:07 by asendroiu