Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
sesiuni:memory:2 [2013/07/08 11:42]
asendroiu [Tasks]
sesiuni:memory:2 [2013/07/09 16:05]
asendroiu [Virtual Memory. Stack]
Line 1: Line 1:
 += Virtual Memory. Stack =
 +* [[sesiuni:​memory:​| Back to workshop]]
 +* {{:​sesiuni:​memory:​session-02.pdf|Download slides}}
 +* {{:​sesiuni:​memory:​session-02-tasks.zip|Download tasks}}
 = Tasks = = Tasks =
 +
 +Rulați ''​make''​ pentru a compila sursele din directorul session-02-tasks.
 +
 +== Memoria Virtuală. Spațiul de adresă ==
   - Formatul ELF   - Formatul ELF
-    * Compilati programul adr_space.c. ​Folosiți utilitarul readelf pentru a afisa informații despre secțiunile executabilului adr_space. (Hint: man readelf, search: sections) +    * 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?+    * Identificați secțiunile ​''​.text''​''​.rodata''​''​.data'' ​și ''​.bss''​. Observați diferențele în coloana ​''​Type'' ​între ​''​.bss'' ​și ''​.data''​. Ce înseamnă ele?
   - Secțiunile unui executabil   - 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) +    * 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. +    * 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. +    * 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?+    * Folosiți ​''​readelf'' ​pentru a căuta secțiunea în care este conținutul variabilei string2. Cum explicați?
   - Layout-ul procesului în memorie   - 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. +    * 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.+    * 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?     * 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"​. ​         *  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? +        * 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+ 
 +== Stiva == 
 +  - Rulați programul ''​return_array''​. De ce nu funcționează?​ Corectați programul astfel încât să funcționeze corect. 
 +  - Rulați programul ''​params''​. Cum explicați comportamentul?​ 
 +  - Rulați programul ''​stackframe''​. Programul realizează apelurile de funcții ''​main''​ -> ''​f''​ -> ''​g''​. 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 == 
 +  - Rulați programul ''​bug''​. Vom folosi GDB pentru a identifica motivul erorii. 
 + 
 +<​code>​ 
 +gdb ./bug 
 +</​code>​ 
 + 
 +<​code>​ 
 +(gdb) run 
 +</​code>​ 
 + 
 +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. 
 + 
 +<​code>​ 
 +(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 
 +</​code>​ 
 + 
 +Folosiți comanda ''​frame''​ pentru a vă muta în cadrul unui alt frame din stiva de apeluri 
 +<​code>​ 
 +(gdb) frame 1 
 +#1  0x080484c5 in allocate (n=5) at bug.c:31 
 +31 initialize(w,​ n); 
 +</​code>​
  
-=== Fun ===+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 ==
   - 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?   - 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?
  
sesiuni/memory/2.txt · Last modified: 2013/07/09 16:07 by asendroiu