Differences

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

Link to this comparison view

so:laboratoare:laborator-05 [2019/03/16 23:42]
ioana_elena.ciornei [Exercițiul 4 - Rezolvarea unei probleme de tip Segmentation Fault]
so:laboratoare:laborator-05 [2022/03/02 09:32] (current)
teodor_stefan.dutu [Exercițiul 0 - GSOC]
Line 1: Line 1:
 ====== Laborator 05 - Gestiunea memoriei ====== ====== Laborator 05 - Gestiunea memoriei ======
    
-===== Materiale ajutătoare ===== 
  
-  *[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-slides.pdf | lab05-slides.pdf]] 
-  *[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-refcard.pdf | lab05-refcard.pdf]] 
  
 ==== Nice to read ==== ==== Nice to read ====
  
   * TLPI - Chapter 7, ''​Memory Allocation''​   * TLPI - Chapter 7, ''​Memory Allocation''​
 +
 +===== Link-uri către secțiuni utile =====
 +
 +  * [[#​Gestiunea memoriei]]
 +  * [[#Spațiul de adresă al unui proces]]
 +  * [[#​Alocarea/​Dealocarea memoriei]]
 +  * [[#Lucru cu memoria - Probleme]]
 +    * [[#GDB - Detectarea zonei de acces nevalid de tip page fault]]
 +    * [[#mcheck - verificarea consistenței heap-ului]]
 +  * [[#Leak-uri de memorie]]
 +    * [[#​Valgrind]]
 +    * [[#mtrace]]
 +    * [[#Dublă dealocare]]
 +  ​
  ===== Gestiunea memoriei =====  ===== Gestiunea memoriei =====
  
Line 23: Line 34:
  
 Este, în consecință,​ fundamentală cunoașterea contextului în care acționează subsistemul de gestiune a memoriei și înțelegerea interfeței puse la dispoziție programatorului de către sistemul de operare. Este, în consecință,​ fundamentală cunoașterea contextului în care acționează subsistemul de gestiune a memoriei și înțelegerea interfeței puse la dispoziție programatorului de către sistemul de operare.
 +
 ===== Spațiul de adresă al unui proces ===== ===== Spațiul de adresă al unui proces =====
  
Line 317: Line 329:
  DIE (mat == NULL, "​HeapAlloc"​);​  DIE (mat == NULL, "​HeapAlloc"​);​
      
- for (i = 0; i < n; i++) {+ for (i = 0; i < m; i++) {
  mat[i] = HeapAlloc(processHeap,​ 0, n * sizeof(**mat));​  mat[i] = HeapAlloc(processHeap,​ 0, n * sizeof(**mat));​
  if (mat[i] == NULL) {  if (mat[i] == NULL) {
Line 842: Line 854:
 ====== Exerciții ====== ====== Exerciții ======
  
-===== Exercițiul 0 Joc interactiv =====+<note important>​ 
 +În cadrul laboratoarelor vom folosi repository-ul de git al materiei SO - https://​github.com/​systems-cs-pub-ro/​so. Va trebui sa clonați repository-ul pe masinile virtuale folosind comanda: ''​git clone https://​github.com/​systems-cs-pub-ro/​so''​. Dacă doriți să descărcați repositoryul în altă locație, folosiți comanda ''​git clone https://​github.com/​systems-cs-pub-ro/so ${target}''​.
  
-  * Detalii desfășurare [[http://​ocw.cs.pub.ro/courses/​so/​meta/​notare#​joc_interactiv|joc]].+Pentru a actualiza repository-ul,​ folosiți comanda ''​git pull origin master''​ din interiorul directorului în care se află repository-ulRecomandarea este să îl actualizați cât mai frecvent, înainte să începeți lucrul, pentru a vă asigura că aveți versiunea cea mai recentăÎn cazul în care gitul detectează conflicte la nivelul vreunui fişier, folosiți următoarele comenzi pentru a vă păstra modificările:​ 
 +<​code>​ 
 +git stash 
 +git pull origin master 
 +git stash pop 
 +</code>
  
 +Pentru mai multe informații despre folosirea utilitarului git, urmați ghidul de la https://​gitimmersion.com.
 +</​note>​
  
 +<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile.
 +</​note>​
  
 +==== Exercițiul 0 - GSOC ====
  
-===== Linux =====+Google Summer of Code este un program de vară în care studenții 
 +(indiferent de anul de studiu) sunt implicați în proiecte Open Source 
 +pentru a își dezvolta skill-urile de programare, fiind răsplătiți cu o 
 +bursă a cărei valoare [[https://​developers.google.com/​open-source/​gsoc/​help/​student-stipends|depinde de țară]] 
 +([[https://​developers.google.com/​open-source/​gsoc|pagină principală GSOC]]).
  
-<note important>​În rezolvarea laboratorului folosiți arhiva de sarcini [[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-tasks.zip | lab05-tasks.zip]]</​note>​+UPB se află în top ca număr de studenți acceptați; în fiecare an fiind 
 +undeva la aprox30-40 de studenți acceptați. 
 +Vă încurajăm să aplicați! 
 + 
 +===== Linux =====
  
-<note tip>​Pentru a vă ajuta la implementarea exercițiilor din laborator, în directorul ''​utils''​ din arhivă există un fișier ''​utils.h''​ cu funcții utile. 
-</​note>​ 
 ==== Exercițiul 1 - Zone de stocare a variabilelor ==== ==== Exercițiul 1 - Zone de stocare a variabilelor ====
  
 Intrați în directorul ''​1-counter''​ și implementați funcția ''​inc()''​ care întoarce de fiecare dată un întreg reprezentând numărul de apeluri până în momentul respectiv al funcției ''​inc''​ (**nu** aveți voie să folosiți variabile globale). Intrați în directorul ''​1-counter''​ și implementați funcția ''​inc()''​ care întoarce de fiecare dată un întreg reprezentând numărul de apeluri până în momentul respectiv al funcției ''​inc''​ (**nu** aveți voie să folosiți variabile globale).
- 
  
 ==== Exercițiul 2 - Spațiul de adresă al unui proces ==== ==== Exercițiul 2 - Spațiul de adresă al unui proces ====
Line 892: Line 920:
 ==== Exercițiul 4 - Rezolvarea unei probleme de tip Segmentation Fault ==== ==== Exercițiul 4 - Rezolvarea unei probleme de tip Segmentation Fault ====
  
-Intrați în directorul ''​4-gdb''​ și inspectați sursa. Programul ar trebui să citescă un mesaj de la ''​stdin'',​ să transforme fiecare literă ​într-o ​majusculă și apo să-l afișeze. Compilați și rulați sursa.+Intrați în directorul ''​4-gdb''​ și inspectați sursa. Programul ar trebui să citescă un mesaj de la ''​stdin'',​ să îi transforme fiecare literă ​în majusculă și apoi să-l afișeze. Compilați și rulați sursa.
  
 Rulați încă o dată programul din ''​gdb''​ (revedeți [[so:​laboratoare-2013:​resurse:​gdb#​rulare gdb|rularea unui program din gdb]] și  [[#acces nevalid | detectarea unui acces nevalid de tip page fault]]): Rulați încă o dată programul din ''​gdb''​ (revedeți [[so:​laboratoare-2013:​resurse:​gdb#​rulare gdb|rularea unui program din gdb]] și  [[#acces nevalid | detectarea unui acces nevalid de tip page fault]]):
Line 929: Line 957:
    * Explicați sursa erorii, apoi rezolvați-o.    * Explicați sursa erorii, apoi rezolvați-o.
  
 +<note tip>
 +  * https://​stackoverflow.com/​questions/​40290049/​why-does-gcc-return-0-instead-of-the-address-of-a-stack-allocated-variable
 +  * https://​github.com/​gcc-mirror/​gcc/​commit/​f22a2cb7500755d69ee5965985d8621c735579c0
 +</​note>​
 ==== Exercițiul 5 - Lucru cu memoria - Valgrind ==== ==== Exercițiul 5 - Lucru cu memoria - Valgrind ====
  
Line 945: Line 977:
       * în funcția ''​take_snapshot''​ salvați în structura de date ce reține imaginea stivei câmpurile adresă și valoare.       * în funcția ''​take_snapshot''​ salvați în structura de date ce reține imaginea stivei câmpurile adresă și valoare.
  
-Ce reține structura ''​stack_elements''?​+Ce reține structura ''​stack_element''?​
  
 Funcția ''​f2''​ pune pe stivă un vector de 3 întregi. În ce ordine sunt puse elementele vectorului pe stivă? Funcția ''​f2''​ pune pe stivă un vector de 3 întregi. În ce ordine sunt puse elementele vectorului pe stivă?
Line 952: Line 984:
  
 <note tip> <note tip>
-Dezasamblați executabilul. Observați că înainte de call ''​f2''​ se pune pe stivă ''​instruction pointer-ul(eip)''​ care este adresa primului byte de după call. La intrarea în funcție controlul s-a transmis de la caller la callee. Acesta din urmă salvează vechiul ''​base pointer(ebp)''​ iar ebp va conține adresa vârfului stivei.+Dezasamblați executabilul. Observați că înainte de call ''​f2''​ se pune pe stivă ''​instruction pointer-ul(eip) / rip (x86-64)''​ care este adresa primului byte de după call. La intrarea în funcție controlul s-a transmis de la caller la callee. Acesta din urmă salvează vechiul ''​base pointer(ebp) / rbp (x86-64)''​ iar ebp va conține adresa vârfului stivei.
 </​note>​ </​note>​
  
-Folosiți gdb pentru a afla informații despre cum este pus array-ul pe stivă ​și ce index trebuie suprascris: <code bash>+Folosiți gdb pentru a afla informații despre cum este pus array-ul pe stivă: <code bash>
 (gdb) break f2 (gdb) break f2
 (gdb) run (gdb) run
Line 961: Line 993:
 </​code>​ </​code>​
  
-Aveți grijă la proctectori ​de stivă [[https://​mudongliang.github.io/​2016/​05/​24/​stack-protector.html|Stack protectors]].+Aveți grijă la protectori ​de stivă [[https://​mudongliang.github.io/​2016/​05/​24/​stack-protector.html|Stack protectors]].
  
-In funcția ''​f2''​ bufferul ''​v''​ se află pe stivă sub adresa de return a funcției (IP-ul la care se întoarce programul dupa ce execută ''​f2''​). Scriind în bufferul ''​v''​ mai multe elemente decat are acesta alocate pe stivă, vom putea suprascrie adresa de return a lui ''​f2''​ cu o alta adresă (aici, adresa funcției ''​show_message''​). Atenție, după adresa de return este salvat pe stivă base pointerul și abia apoi găsim și bufferul ''​v''​.+In funcția ''​f2''​ bufferul ''​v''​ se află pe stivă sub adresa de return a funcției (IP-ul la care se întoarce programul dupa ce execută ''​f2''​). Scriind în bufferul ''​v''​ mai multe elemente decat are acesta alocate pe stivă, vom putea suprascrie adresa de return a lui ''​f2''​ cu o altă adresă (aici, adresa funcției ''​show_message''​). Atenție, după adresa de return este salvat pe stivă base pointerul și abia apoi găsim și bufferul ''​v''​.
  
 Folosindu-vă de vectorul ''​v''​ **fortați execuția** funcției ''​show_message''​ **fără** a o apela explicit. Astfel, după apelul funcției ''​f2'',​ fluxul programului nu se va mai întoarce în funcția ''​f1'',​ ci va executa ''​show_message''​. Urmăriți comentariile marcate cu //TODO2// (revedeți partea din laborator referitoare la [[#stiva | stivă ]]) Folosindu-vă de vectorul ''​v''​ **fortați execuția** funcției ''​show_message''​ **fără** a o apela explicit. Astfel, după apelul funcției ''​f2'',​ fluxul programului nu se va mai întoarce în funcția ''​f1'',​ ci va executa ''​show_message''​. Urmăriți comentariile marcate cu //TODO2// (revedeți partea din laborator referitoare la [[#stiva | stivă ]])
 +Folosiți-vă de cum arată stiva pentru a afla indexul în cadrul vectorului ''​vv''​ la care se află IP-ul.
 +
  
 <note tip> <note tip>
Line 985: Line 1019:
  
  
-==== Exercițiul 9 - Lucrul cu stiva ====+<​hidden>​==== Exercițiul 9 - Lucrul cu stiva ====
  
 Intrați în directorul ''​9-bad_stack''​ și analizați fișierul ''​bad_stack.c''​. Compilați și rulați programul. Intrați în directorul ''​9-bad_stack''​ și analizați fișierul ''​bad_stack.c''​. Compilați și rulați programul.
Line 996: Line 1030:
  
 <note tip>​Indicație:​ Mutați variabila ''​lab_so''​ din funcția ''​my_fun()''​ într-o altă zonă de memorie.</​note>​ <note tip>​Indicație:​ Mutați variabila ''​lab_so''​ din funcția ''​my_fun()''​ într-o altă zonă de memorie.</​note>​
- +</​hidden>​ 
-===== Exerciții BONUS (3 SO Karma) ​===== +===== Exerciții BONUS ===== 
  
 ==== BONUS Windows ==== ==== BONUS Windows ====
Line 1027: Line 1061:
 <note tip>​Pentru rularea programului de test, nu uitați să exportați ''​LD_LIBRARY_PATH''​ (revedeți secțiunea de [[so:​laboratoare-2013:​laborator-01#​biblioteci in linux | biblioteci partajate din laboratorul 1]])</​note>​ <note tip>​Pentru rularea programului de test, nu uitați să exportați ''​LD_LIBRARY_PATH''​ (revedeți secțiunea de [[so:​laboratoare-2013:​laborator-01#​biblioteci in linux | biblioteci partajate din laboratorul 1]])</​note>​
  
-===== Soluții ===== 
- 
-[[http://​elf.cs.pub.ro/​so/​res/​laboratoare/​lab05-sol.zip | lab05-sol.zip]] 
  
 ===== Resurse utile ===== ===== Resurse utile =====
so/laboratoare/laborator-05.1552772549.txt.gz · Last modified: 2019/03/16 23:42 by ioana_elena.ciornei
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0