Examen CA/CB/CC 2019-2020

Urmăriți precizările din pagina de reguli.

Examen final

Puteți participa la un singur examen final.

Datele de examen de SO pentru sesiunea iunie 2020 sunt:

  • TODO
  • TODO
  • TODO

Datele de examen de SO pentru sesiunea septembrie 2019 sunt:

  • TODO

Puteți veni o singură dată la examen. Studenții care refac materia pot veni doar în primele două date de examen (TODO și TODO). Pentru ei sesiunea este mai scurtă (TODO - TODO).

Studenții de anul 3 pot veni în alte zile față de cea aferentă grupei/seriei lor. Studenții în alte situații (de exemplu transferați de la IS) pot veni oricând. Cei care doresc să vină în altă zi față de cele alocate, să trimită un e-mail către Elena cu subiectul [SO][Examen] Transfer: Prenume NUME, grupă, de exemplu [SO][Examen] Transfer: Ana POPESCU, 332CB.

Informații despre desfășurătorul și conținutul examenului găsiți în secțiunea aferentă din pagina de notare. În pregătirea examenului recomandăm să parcurgeți subiectele de examen anterioare.

Urmăriți precizările din pagina de reguli.

Foi de examen

  • TODO ( TODO )

Lucrări

  • Dacă nu puteți participa la seria fiecăruia, puteți veni la cealaltă serie. Pentru aceasta trimiteți un e-mail catre Elena cu subiectul [SO][Lucrare X] Transfer Prenume Nume, Grupa unde:
    • X este indexul lucrării (1, 2, 3 sau 4)
    • Prenume este prenumele.
    • Nume este numa.
    • Grupa este grupa.
  • Nu există sesiune de contestații propriu-zisă; dacă sunteți de părere că nu a fost corectată corespunzător lucrarea, trimiteți un e-mail (solicitare de recorectare) către Veronica Radu. Cererile de recorectare se vor trimite după publicarea soluțiilor pe această pagină, până la data limită anunțată pe lista de discuții.
    • Folosiți subiectul [SO][Lucrare X] Prenume NUME - grupa; de exemplu [SO][Lucrare 1] Andreea POPESCU - 332CA.
  • Pentru a fi punctat, răspunsul la o întrebare trebuie să fie justificat.

Lucrare 1

  • La începutul cursului 5:
    • 09.03.2020, seria CA
    • 05.03.2020, seria CB
    • 04.03.2020, seria CC

3CA, varianta 1

  1. Într-un sistem de operare cu suport de multithreading (sau cu mai multe procesoare), un proces are deschise fișiere doar cu descriptorii 0, 1 și 2. Ce se intamplă după executarea următoarei secvențe? Argumentați răspunsul.
    close(0);
    dup(1); 
    • Răspuns: Se va crea un descriptor nou, către același FCB cu descriptorul 1. Cel mai probabil valoarea lui va fi 0, dacă nu există alte thread-uri în proces care au ocupat descriptorul între timp.
  2. Care sunt operațiile ce trebuie executate pentru a realiza un apel de sistem?
    • Răspuns: Procesul pune în regiștrii procesorului parametrii apelului de sistem și execută o instrucțiune privilegiată, de exemplu int sau sysenter.
  3. Un proces apelează:
    printf("123\n456");
    int *p = NULL;
    *p = 3; 

    Pe ecran apare doar 123. De ce nu s-au afișat ambele numere?

    • Răspuns: printf foloseste un buffer în userspace care este golit din când în când (în general la \n). Procesul a fost închis din cauza unui acces ilegal la memorie și nu a mai apucat să trimită tot bufferul la kernel.

3CA, varianta 2

  1. Sunt echivalente întotdeauna următoarele doua secvente de instructiuni? Argumentați răspunsul.
    /* Secvența 1 */                 | /* Secvența 2 */
    close(1);                        | dup2(3,1); 
    dup(2);                          | 
    • Răspuns: Nu sunt echivalente. E posibil ca cel mai mic file descriptor să fie 0 și e posibil ca între close și dup să fie un thread care ocupă file descriptorul 1.
  2. De ce sunt necesare apelurile de sistem în sisteme de operare?
    • Răspuns: Există cel putin două nivele de privilegii de execuție pe procesor. Pentru a efectua acțiuni privilegiate precum accesul la periferice, este nevoie de nivelul privilegiat. Procesele nu pot executa toate instrucțiunile procesorului, fiind nevoie de un nivel de privilegii suplimentar.
  3. Un proces apelează fgets (stdin, buffer, 100); prima dată la pornire și a doua oară după 1 minut. Observăm că al doilea apel întoarce imediat în buffer un string Argumentați de ce/
    • Răspuns: Utilizatorul a introdus prima dată două rânduri de text, ambele mai scurte de 100 de caractere. Acestea au fost transferate în buffer-ul programului, al doilea apel al fgets a luat datele direct din buffer.

3CB, varianta 1

  1. Se creează un nou fișier folosind apelul open și se scriu în acesta 512 octeți folosind apelul write. Ulterior, se apelează lseek(file, -256, SEEK_CUR). Presupunând că toate apelurile de sistem s-au încheiat cu succes, iar apelul write a scris tot buffer-ul, care va fi dimensiunea fișierului? Argumentați.
    • Răspuns: Dimensiunea fișierului va fi 512 octeți (deoarece apelul open a reușit, fișierul a fost creat; deoarece apelul write a scris tot buffer-ul, dimensiunea fișierului este 512). Apelul lseek nu modifică dimensiunea fișierului, ci mută doar cursorul de fișier.
  2. De ce este limitată dimensiunea tabelei de descriptori de fișier într-un sistem de operare? Argumentați răspunsul.
    • Răspuns: Dimensiunea tabelei de fișiere a unui proces este limitată din rațiuni de securitate. În cazul în care dimensiunea nu ar fi limitată, deschiderea un număr foarte mare de fișiere, de exemplu într-o buclă while, ar bloca sistemul de operare.
  3. Precizați un avantaj al folosirii funcției CreateProcess din Windows față de combinația fork + exec din Linux. Argumentați răspunsul.
    • Răspuns: Un avantaj al funcției CreateProcess este că aceasta crează direct procesul dorit încărcându-i imaginea, în timp ce combinația fork+exec aduce overhead mai întâi clonând imaginea procesului părinte (fork) pe care o înlocuiește cu imaginea procesului dorit (exec).

3CB, varianta 2

  1. Se creează un nou fișier folosind apelul open și se apelează funcția ftruncate(file, 512). Ulterior, în același fișier se scriu 32 de octeți. Care va fi dimensiunea finală a fișierului? Argumentați.
    • Răspuns: Considerând că fișierul este nou creat, dimensiunea acestuia înainte de ftruncate este 0. Apelul ftruncate modifică dimensiunea acestuia la 512 octeți, dar lasă cursorul de fișier nemodificat (valoare 0). În urma apelului write, cursorul de fișier ajunge la valoarea 32, deci nu se modifică dimensiunea fișierului, care rămâne 512.
  2. Numiți un avantaj al folosirii dup2 în detrimentul folosirii dup. Argumentați.
    • Răspuns: Apelul dup2 primește ca parametru atât ce file descriptor să duplice, cât și cel pe care să îl suprascrie. Acest lucru permite duplicarea pe o poziție care nu este secvențial crescătoare față de descriptorii deja existenți - ex., într-un program care are doar descriptorii 0-2 deschiși, apelul dup2(1, 42) ar putea fi imitat prin 40 de apeluri dup, urmată de 39 de apeluri de close.
  3. Precizați două proprietăți pe care un proces copil (creat prin intermediul funcției fork()) le moștenește de la procesul părinte. Explicați.
    • Răspuns: Procesul copil moștenește tabela de fișiere, utilizatorul care a creat procesul și memoria (zona de cod / date în mod read-only) de la procesul părinte.

3CC, varianta 1

  1. Dați un exemplu de operație / acțiune care trebuie realizată în spațiul kernel (kernel space) și una care poate fi realizată în spațiul utilizator (user space). Justificați
    • Răspuns: Apelul fork() trebuie realizat în spațiul kernel, deoarece se duplică structuri ce se află deja în kernel. Un apel către fprintf poate să se realizeze doar în user space. Momentul în care se face un apel de sistem este când este afișat un terminator de linie nouă, sau bufferul intern ajunge la capacitatea maximă. Alte apeluri care se realizează exclusiv în user space sunt apelurie de lucru pe șiruri (strcpy, strlen), care nu execută apeluri de sistem.
  2. Un fișier este deschis. Dați un exemplu de apel care modifică atât dimensiunea fișierului, cât și cursorul de fișier. Și un exemplu de apel care modifică doar dimensiunea fișierului (nu și cursorul de fișier). Justificați.
    • Răspuns: Un apel de funcție care modifică atât dimensiunea cât și cursorul fișierului este write. Exemplu: write(myFd, bigBuf, 1) (cu presupunerea că avem cursorul la finalul fișierului). Un apel de funcție care modifică dimensiunea, dar nu și cursorul unui fișier este ftruncate. Exemplu: ftruncate(myFd, 1073741824)
  3. Într-un shell rulăm ls /a/b/c/ && ps. Câte apeluri fork(), exec() și wait() au loc și în ce ordine? Justificați.
    • Răspuns: Presupunând că prima comandă nu întoarce exit code nenul, vom avea ordinea: Shell - fork(), Copil1 - exec(), Shell - wait(), Shell - fork(), Copil2 - exec(), Shell - wait(). În cazul în care prima comandă întoarce exit code nenul, se vor executa primele 3.

3CC, varianta 2

  1. De ce tabela de descriptori de fișiere este reținută în spațiul kernel (kernel space) și nu în spațiul utilizator (user space)? Justificați.
    • Răspuns: Stocarea FDT în user space ar implica faptul că userland are pointeri valizi către structuri din kernel (din tabela de fișiere deschise). Deși nu avem acces de citire/scriere din userspace la spațiul de adresă al kernelului, un atacator ar putea ghici adrese unde se află alte structuri de tip open file, potențial aparținând altor utilizatori (inclusiv root), și astfel ar putea asambla un descriptor către un fișier care nu-i aparține, în care poate citi sau scrie.
  2. Un program apelează funcția print_all_info() care afișează informații la ieșirea standard. Dorim ca acele informații (și doar acelea) să fie afișate în fișierul “results.txt”. Adică după apelul funcției, alte afișări să se facă în continuare la ieșirea standard. Completați zonele cu TODO din secvența de cod de mai jos care să ducă la rezultatul dorit:
        /* TODO */
        print_all_info();  /* prints in "results.txt" file */
        /* TODO */
        printf("aaa\n");  /* prints at standard output */ 
    • Răspuns:
      backup_stdout = dup(STDOUT_FILENO);
      file_fd = open(“results.txt”, O_RDWR | O_CREAT | O_TRUNC, 0644);
      dup2(file_fd, STDOUT_FILENO);
      close(file_fd);
      print_all_info();  /* prints in “results.txt” file */
      dup2(backup_stdout, STDOUT_FILENO);
      close(backup_stdout);
      printf("aaa\n");  /* prints at standard output */ 
  3. De ce, în general, apelul exec() durează mai mult decât apelul fork()? Justificați.
    • Răspuns: Apelurile din familia exec() înlocuiesc imaginea procesului cu una specificată printr-o cale pe disk. Acest lucru implică I/O, posibilă încărcare de pe disk, apelarea loaderului. Toate acestea sunt mult mai costisitoare decât apelul fork(), care copiază doar date din RAM tot în RAM

Greșeli frecvente

  • Răspunsuri incomplete, ambigue, parțial corecte, pe lângă subiect.
  • Confuzie între apeluri de sistem și procese noi. O greșeală frecvent întâlnită este următoarea: Pentru un apel de sistem se foloseste fork() + execv + wait.
  • Procesul moștenește pid-ul procesului părinte. PID-ul nu este o proprietate care este moștenită.
  • Procesul copil “moștenește” sistemul de fișiere. Sistemul de fișiere este o resursă partajată între toate programele; sistemul de fișere nu este (cu excepția programelor rulate într-un sandbox de tip jail / chroot) specific unui anumit proces.
  • Odată închis stdout, el nu mai poate fi redeschis. STDOUT_FILENO este un simplu macro care se reduce, de cele mai multe ori, la numărul “1”.
  • Confuzii între apelul exec și apelul system.

Lucrări foarte bune

Lucrare 2

  • La începutul cursului 9:
    • 24.03.2020, seria CA
    • 25.03.2020, seria CB
    • 25.03.2020, seria CC

3CA, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CA, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

Greșeli frecvente

Lucrări foarte bune

Lucrare 3

  • La începutul cursului 13:
    • 13.04.2020, seria CA
    • 15.04.2020, seria CB
    • 13.04.2020, seria CC

3CA, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CA, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

Greșeli frecvente

.

Lucrări foarte bune

Lucrare 4

  • La începutul cursului 18:
    • 18.05.2020, seria CA
    • 14.05.2020, seria CB
    • 13.05.2020, seria CC

3CA, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CA, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CB, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 1

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

3CC, varianta 2

  1. TODO
    • Răspuns: TODO
  2. TODO
    • Răspuns: TODO
  3. TODO
    • Răspuns: TODO

Greșeli frecvente

Lucrări foarte bune

so/meta/examen/2019-2020.txt · Last modified: 2020/03/14 17:49 by maria.mihailescu
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