Differences

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

Link to this comparison view

so:laboratoare:resurse:recapitulare [2013/01/31 21:57]
127.0.0.1 external edit
so:laboratoare:resurse:recapitulare [2022/03/14 18:02] (current)
teodor_stefan.dutu [Exerciții] Rework exercise 1
Line 3: Line 3:
 Laboratorul constă în subiecte în stilul celor de la examen, însoțite de mici bucăți de cod complete sau aproape complete pe care le puteți rula pentru a vă convinge. Discuția pe marginea subiectelor cu asistentul sau cu colegii este încurajată. Subiectele sunt suficient de multe încât nu pot fi acoperite într-un singur laborator. Laboratorul constă în subiecte în stilul celor de la examen, însoțite de mici bucăți de cod complete sau aproape complete pe care le puteți rula pentru a vă convinge. Discuția pe marginea subiectelor cu asistentul sau cu colegii este încurajată. Subiectele sunt suficient de multe încât nu pot fi acoperite într-un singur laborator.
 ===== Exerciții ===== ===== Exerciții =====
-Utilizați arhiva [[http://​elf.cs.pub.ro/​so/​wiki/​_media/​laboratoare/​resurse/​recap.tar.gz | recap.tar.gz]] aferentă laboratorului. 
  
-Demand-paging,​ Copy-on-Write. Intrați în directorul ​{{{01-cow-dp}}}.  +  - Demand-paging,​ Copy-on-Write. Intrați în directorul ​''​01-cow''​.  
-#* Rulați comanda:<​code>​ +    * Rulați comanda ​''​make''​ și rulați executabilul creat''​cow''​. 
-make && make run +    * **Explicați** ​când au loc evenimentele ​de Demand-paging și de Copy-on-Write. 
-</​code>​ +    * De ce scrierea efectuată de procesul copil în paginile ​alocate ​de părinte dureaza mult mai mult decât citirile? 
-#* **Explicați** ​apariția evenimentelor ​de Demand-paging și de Copy-on-Write. +  - Subsistemul IO. Intraţi în directorul ​''​02-io'' ​şi inspectaţi fişierul ​''​splice.c''​.  
-#* Pentru testare, utilizați fișierele: {{{fault/​fault}}} și {{{fault2/​fault}}}. +    * Închipuiţi-vă scenariul în care programul rulează repede şi un alt scenariu în care rulează greu (din punctul de vedere al timpului). 
-#* De ce la ultima pagină din buffer (din fișierul {{{fault/​fault}}}) nu se mai face Demand-paging?​ +    * **Hints**:​ 
-#* **Hints**:​ +      * Ce operaţii se fac la trunchierea fişierului?​ 
-#** paginile ​**gri** reprezintă pagini muliple nemapate reprezentate într-un interval +      * Care este rolul fişierului [[http://​www.linuxinsight.com/​proc_sys_vm_drop_caches.html | /​proc/​sys/​vm/​drop_caches]]? 
-#** paginile **verzi** reprezintă pagini ce aparțin unui singur proces +      * Ce fel de mecanism implementează apelul de sistem ​''​splice''​
-#** paginile **roșii** sunt pagini partajate ​de cel puțin două procese +      * **Atenţie**:​ Asigurați-vă că sistemul dispune de suficientă memorie (RAM) liberă pentru a putea aduce tot fișierul în RAM (i.e. dimensiunea memorie liberă > dimensiunea fișierului). 
-#** la **click** pe o pagină se centrează pagina respectivă și toate paginile legate de ea +      * Utilizaţi scriptul ​''​run.sh''​: <​code>​sudo ./​run.sh</​code>​ 
-#** după ce a a apărut un eveniment de tipul Copy-on-Write **un** click duce la pagina la care este mapată acum, **următorul** click va duce la pagina veche la care era mapată +      * **Ignoraţi mesajul**:<​code>​Command terminated by signal 13</​code>​ 
-Subsistemul IO. Intraţi în directorul ​{{{02-io}}} şi inspectaţi fişierul ​{{{splice.c}}}.  +  ​- ​Threads counter (LD): Un proces crează N thread-uri și un thread apelează fork(); câte threaduri, atât în procesul părinte cât și în procesul copil, există imediat după acest moment? Studiați conținutul directorului ​''​03-threads-counter''​. În ce director din ''​/proc/$PID/'' ​se află informațiile despre thread-urile procesului? De ce acestea au asignat un pid? 
-#* Închipuiţi-vă scenariul în care programul rulează repede şi un alt scenariu în care rulează greu (din punctul de vedere al timpului). +  ​- ​Function hijacking (LD): De ce în cazul folosirii LD_PRELOAD se pot intercepta apeluri de funcții? Intrați în directorul ​''​04-functions-hijacking''​, compilați (''​make''​) și rulați (''​./test'' ​și ''​LD_PRELOAD=./​libnative.so ./test''​. Cum explicați output-ul diferit? 
-#* **Hints**:​ +  ​- ​Inițializări (VD): Intrați în directorul ​''​05-init''​. Compilați programul ​''​initializari''​. De ce durează mai mult prima inițializare?​ De asemenea, încercați să explicați dimensiunea mare a executabilului. 
-#** Ce operaţii se fac la trunchierea fişierului?​ +  ​- ​Spațiu de adresă (AF): Intrați în directorul ​''​06-addrspc'' ​și inspectați fișierul ​''​addrspc.c''​. Ce se întâmplă cu spațiul de adresă al procesului în momentul schimbării de context? 
-#** Care este rolul fişierului [[http://​www.linuxinsight.com/​proc_sys_vm_drop_caches.html | /​proc/​sys/​vm/​drop_caches]] +    * **Hints**:​ 
-#** Ce fel de mecanism implementează apelul de sistem ​{{{splice}}}+      * Threadurile rulează alternativ, scriind la stdout atunci când încep rularea 
-#** **Atenţie**:​ Asigurați-vă că sistemul dispune de suficientă memorie (RAM) liberă pentru a putea aduce tot fișierul în RAM (i.e. dimensiunea memorie liberă > dimensiunea fișierului). +      * Monitorizați ​''​/​proc/​$PID/​maps''​ 
-#** Utilizaţi scriptul ​{{{run.sh}}}: <​code>​sudo ./​run.sh</​code>​ +  ​- ​Reentranță / thread-safety (AF): Catalogați funcțiile din ''​07-reentr/​reentr.c'' ​ca fiind reentrante / thread-safe. Puteți modifica programul încât să puneți în evidență aceste aspecte. 
-#** **Ignoraţi mesajul**:<​code>​Command terminated by signal 13</​code>​ +  ​- ​Stack growth (VD): Scrieți o secvență de cod care să decidă dacă stiva crește în sus sau în jos. Un asemenea exemplu îl aveți în directorul ​''​08-stack-growth''​
-Threads counter (LD): Un proces crează N thread-uri și un thread apelează fork(); câte threaduri, atât în procesul părinte cât și în procesul copil, există imediat după acest moment? Studiați conținutul directorului ​{{{03-threads-counter}}}.În ce director din {{{/proc/$PID/}}} se află informațiile despre thread-urile procesului? De ce acestea au asignat un pid? +  ​- ​Apeluri de sistem (DB): Câte apeluri de sistem se efectuează în urma rulării secvenţei de mai jos:<​code c>
-Function hijacking (LD): De ce în cazul folosirii LD_PRELOAD se pot intercepta apeluri de funcții? Intrați în directorul ​{{{04-functions-hijacking}}}, compilați ({{{make}}}) și rulați ({{{./test}}} și {{{LD_PRELOAD=./​libnative.so ./test}}}. Cum explicați output-ul diferit? +
-Inițializări (VD): Intrați în directorul ​{{{05-init}}}. Compilați programul ​{{{initializari}}}. De ce durează mai mult prima inițializare?​ De asemenea, încercați să explicați dimensiunea mare a executabilului. +
-Spațiu de adresă (AF): Intrați în directorul ​{{{06-addrspc}}} și inspectați fișierul ​{{{addrspc.c}}}. Ce se întâmplă cu spațiul de adresă al procesului în momentul schimbării de context? +
-#* **Hints**:​ +
-#** Threadurile rulează alternativ, scriind la stdout atunci când încep rularea +
-#** Monitorizați ​{{{/​proc/​$PID/​maps}}} +
-Reentranță / thread-safety (AF): Catalogați funcțiile din {{{07-reentr/​reentr.c}}} ca fiind reentrante / thread-safe. Puteți modifica programul încât să puneți în evidență aceste aspecte. +
-Stack growth (VD): Scrieți o secvență de cod care să decidă dacă stiva crește în sus sau în jos. Un asemenea exemplu îl aveți în directorul ​{{{08-stack-growth}}}+
-Apeluri de sistem (DB): Câte apeluri de sistem se efectuează în urma rulării secvenţei de mai jos:<​code c>+
    for (i = 0; i < 10; i++) {    for (i = 0; i < 10; i++) {
                 getpid();                 getpid();
Line 42: Line 32:
    }    }
 </​code>​ </​code>​
-#* Intrați în directorul ​{{{09-syscall}}}+    ​* Intrați în directorul ​''​09-syscall''​
-#* Analizaţi conţinutul fişierului ​{{{pid_test.c}}}+    * Analizaţi conţinutul fişierului ​''​pid_test.c''​
-#* Urmăriţi apelurile de system efectuate rulând comanda ''​strace''​. <code bash>+    * Urmăriţi apelurile de system efectuate rulând comanda ''​strace''​. <code bash>
 strace ./​pid_test ​ strace ./​pid_test ​
 </​code>​ </​code>​
-#* **Suplimentar** +    ​* **Suplimentar** 
-#** Analizaţi conţinutul fişierului ​{{{fork_test.c}}}+      * Analizaţi conţinutul fişierului ​''​fork_test.c''​
-#** Rulaţi programul având pentru ''​SYS_TYPE''​ pe rând valorile ''​SYS_NATIVE''​ şi ''​SYS_GLIBC''​. +      * Rulaţi programul având pentru ''​SYS_TYPE''​ pe rând valorile ''​SYS_NATIVE''​ şi ''​SYS_GLIBC''​. ​ *Explicaţi rezultatul obţinut. Citiţi secţiunea ''​NOTES''​ din ''​getpid(2)''​. 
-#** Explicaţi rezultatul obţinut. Citiţi secţiunea ''​NOTES''​ din ''​getpid(2)''​. +  ​- ​Creare procese (DB): Desenaţi arborele de procese rezultat în urma execuţiei programului ''​fork.c''​ din directorul ​''​10-fork''​
-Creare procese (DB): Desenaţi arborele de procese rezultat în urma execuţiei programului ''​fork.c''​ din directorul ​{{{10-fork}}}+  ​- ​Descriptori de fisier (OB): Un proces dispune de o tabelă de descriptori de fișiere cu 1024 de intrări. În codul său, procesul deschide un număr mare de fișiere ​ folosind ​ open. Totuși, al 964-lea apel open se întoarce cu eroare, iar errno are valoarea EMFILE (maximum number of files open). Care este o posibilă explicație?​ Vă puteți gândi și la alte explicații decât cea din exemplu? 
-Descriptori de fisier (OB): Un proces dispune de o tabelă de descriptori de fișiere cu 1024 de intrări. În codul său, procesul deschide un număr mare de fișiere ​ folosind ​ open. Totuși, al 964-lea apel open se întoarce cu eroare, iar errno are valoarea EMFILE (maximum number of files open). Care este o posibilă explicație?​ Vă puteți gândi și la alte explicații decât cea din exemplu? +  ​- ​File descriptor (BD): Completați zona punctată de mai jos cu cod Linux(posix) astfel incat sa conduca la afișarea mesajului "​alfa"​ la ieșirea standard (standard output) și mesajul "​beta"​ la ieșirea de eroare standard (standard error), fara sa alterați simbolurile standard fputs (functie), stderr și stdout (FILE *): 
-File descriptor (BD): Completați zona punctată de mai jos cu cod Linux(posix) astfel incat sa conduca la afișarea mesajului "​alfa"​ la ieșirea standard (standard output) și mesajul "​beta"​ la ieșirea de eroare standard (standard error), fara sa alterați simbolurile standard fputs (functie), stderr și stdout (FILE *): +    * <​code>​
-#* <​code>​+
 /* de completat */ /* de completat */
 ... ...
Line 60: Line 49:
 fputs("​beta",​ stdout); fputs("​beta",​ stdout);
 </​code>​ </​code>​
-#* Intrati in directorul ​{{{12-file}}}, si rulati comanda <​code>​./​file >out 2>err </​code>​ +    ​* Intrati in directorul ​''​12-file''​, si rulati comanda <​code>​./​file >out 2>err </​code>​ 
-Calloc/​Malloc (IS): Intrați in directorul ​{{{13-access}}}. Rulați cele 2 programe atât cu macro-ul TEST_ACCESS definit cât și fără acesta. Măsurați timpii de rulare folosind //time// și încercați să explicați diferența. +  ​- ​Calloc/​Malloc (IS): Intrați in directorul ​''​13-access''​. Rulați cele 2 programe atât cu macro-ul TEST_ACCESS definit cât și fără acesta. Măsurați timpii de rulare folosind //time// și încercați să explicați diferența. 
-Apeluri de sistem (RD): În urma rulării secvenței de mai jos:<​code>​+  ​- ​Apeluri de sistem (RD): În urma rulării secvenței de mai jos:<​code>​
  int page_size = getpagesize();​  int page_size = getpagesize();​
  
  for (i = 0; i < 1000; i++)  for (i = 0; i < 1000; i++)
  ptr[i] = malloc(page_size);​  ptr[i] = malloc(page_size);​
-</​code>​ se obține un număr redus de apeluri de sistem, de ordinul zecilor (apelul de sistem folosit de malloc este {{{brk}}}). Cum explicați?​ +</​code>​ se obține un număr redus de apeluri de sistem, de ordinul zecilor (apelul de sistem folosit de malloc este ''​brk''​). Cum explicați?​ 
-#* Intrați în directorul ​{{{14-malloc-syscalls}}}+    * Intrați în directorul ​''​14-malloc-syscalls''​
-#* Urmăriți conținutul fișierului ​{{{malloc-syscalls.c}}}+    * Urmăriți conținutul fișierului ​''​malloc-syscalls.c''​
-#* Compilați fișierul (folosiți ​{{{make}}}). +    * Compilați fișierul (folosiți ​''​make''​). 
-#* Rulați comanda ​{{{strace -e brk ./​malloc-syscall 2>&1 > /dev/null | wc -l}}}+    * Rulați comanda ​''​strace -e brk ./​malloc-syscall 2>&1 > /dev/null | wc -l''​
-#* Rulați comanda ​{{{ltrace -e malloc ./​malloc-syscall 2>&1 > /dev/null | wc -l}}}+    * Rulați comanda ​''​ltrace -e malloc ./​malloc-syscall 2>&1 > /dev/null | wc -l''​
-#* **Suplimentar** +    * **Suplimentar** 
-#** Actualizați macro-ul ​{{{DO_FREE}}} la valoarea 1. +      * Actualizați macro-ul ​''​DO_FREE'' ​la valoarea 1. 
-#** Câte apeluri ​{{{brk}}} au loc? Cum explicați? Ce rol are apelul de sistem ​{{{brk}}}+      * Câte apeluri ​''​brk'' ​au loc? Cum explicați? Ce rol are apelul de sistem ​''​brk''​
-Page fault-uri (RD): Câte page fault-uri se obțin în urma rulării secvenței de mai jos?<​code>​+  ​- ​Page fault-uri (RD): Câte page fault-uri se obțin în urma rulării secvenței de mai jos?<​code>​
  char *p;  char *p;
  int status;  int status;
Line 117: Line 106:
  p[i*page_size] = i;  p[i*page_size] = i;
 </​code>​ </​code>​
-#* Intrați în directorul ​{{{15-faults}}}+    ​* Intrați în directorul ​''​15-faults''​
-#* Urmăriți conținutul fișierului ​{{{fork-faults.c}}}+    * Urmăriți conținutul fișierului ​''​fork-faults.c''​
-#* Compilați fișierul (folosiți ​{{{make}}}). +    * Compilați fișierul (folosiți ​''​make''​). 
-#* Instalați pachetul ​{{{sysstat}}}. Pachetul conține utilitarul ​{{{pidstat}}} care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului ​{{{-r}}}). +    * Instalați pachetul ​''​sysstat''​. Pachetul conține utilitarul ​''​pidstat'' ​care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului ​''​-r''​). 
-#* Rulați programul ​{{{fork-faults}}}. Folosiți ​{{{ENTER}}} pentru a continua programul. +    * Rulați programul ​''​fork-faults''​. Folosiți ​''​ENTER'' ​pentru a continua programul. 
-#* Folosiți comanda ​{{{pidstat -r -T ALL -p $PID}}} pentru a urmări page fault-urile. Rulați comanda pentru fiecare secvență de program. +    * Folosiți comanda ​''​pidstat -r -T ALL -p $PID'' ​pentru a urmări page fault-urile. Rulați comanda pentru fiecare secvență de program. 
-#** {{{$PID}}} reprezintă pid-ul unui proces. Puteți afla atât pid-ul procesului părinte cât și pe cel al procesului copil cu o comandă de forma {{{ps -ef | grep fork-faults}}}+      ''​$PID'' ​reprezintă pid-ul unui proces. Puteți afla atât pid-ul procesului părinte cât și pe cel al procesului copil cu o comandă de forma ''​ps -ef | grep fork-faults''​
-#* Urmăriți evoluția numărului de page fault-uri pentru cele două procese: părinte și copil. Page fault-urile care apar în cazul unui copy-on-write în procesul copil vor fi vizibile ulterior și în procesul părinte.+    * Urmăriți evoluția numărului de page fault-uri pentru cele două procese: părinte și copil. Page fault-urile care apar în cazul unui copy-on-write în procesul copil vor fi vizibile ulterior și în procesul părinte.
so/laboratoare/resurse/recapitulare.1359662221.txt.gz · Last modified: 2013/02/19 09:24 (external edit)
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