This is an old revision of the document!
Urmăriți precizările din pagina de reguli.
Consultați lista de întrebări de la care vom porni discuția pe parcursul examenului.
Puteți participa o singură dată pe sesiune la examenul final.
Datele de examen de SO pentru sesiunea din toamnă, august 2020, sunt:
Datele de examen de SO pentru sesiunea mai 2020 sunt:
Având în vedere situația din acest an, examenul de SO din această sesiune se va desfășura exclusiv online. Modul de examinare va fi asemănător unui examen oral sau al unui interviu. Vom folosi Microsoft Teams ca mediu de comunicare.
Examenul de SO va consta într-un call / interviu de 15 minute cu doi supraveghetori. În decursul acestui examen oral, studentul va fi rugat să răspundă la câteva întrebări din materia de SO adresate de către supraveghetori. Răspunsurile date de către student la întrebarile supraveghetorilor vor fi evaluate cu un punctaj. Nota obținută în cadrul examenului va fi suma punctajelor obținute la toate întrebările.
În timpul examenului veți putea consulta orice material scris sau online. Nu este permisă comunicarea, fie fizică, fie online (Messenger, Instagram, WhatsApp etc.) cu alte persoane în afară de supraveghetori în timpul examenului.
Vom organiza o simulare de examen sâmbătă, 23 mai 2020, ora 14:00, pe Microsoft Teams, 2 ore cu 8 studenți. Vor putea participa toți studenții și toți asistenții dar doar 8 studenți vor fi examinați. Ceilalți studenți vor asista. Simularea se înregistrează, iar studenții nu vor porni camera (din considerente de privacy).
Precizăm că va trebui să aveți la dispoziție, în timpul examenului, o cameră video pentru a vă confirma identitatea, împreună cu un act de identitate. Dacă există situații obiective în care nu veți avea o cameră video în timpul examenului, trimiteți un e-mail către Dragoș cu subiectul [SO][Examen] Cameră video: Prenume NUME, grupă
, de exemplu [SO][Examen] Cameră video: 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 puteți să parcurgeți subiectele de examen anterioare.
Urmăriți precizările din pagina de reguli.
[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.[SO][Lucrare X] Prenume NUME - grupa
; de exemplu [SO][Lucrare 1] Andreea POPESCU - 332CA
.close(0); dup(1);
int
sau sysenter
.printf("123\n456"); int *p = NULL; *p = 3;
Pe ecran apare doar 123
. De ce nu s-au afișat ambele numere?
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./* Secvența 1 */ | /* Secvența 2 */ close(1); | dup2(3,1); dup(2); |
close
și dup
să fie un thread care ocupă file descriptorul 1.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/fgets
a luat datele direct din buffer.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.lseek
nu modifică dimensiunea fișierului, ci mută doar cursorul de fișier.CreateProcess
din Windows față de combinația fork + exec
din Linux. Argumentați răspunsul.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
).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.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.dup2
în detrimentul folosirii dup
. Argumentați.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.fork()
) le moștenește de la procesul părinte. Explicați.ls /a/b/c/ && ps
. Câte apeluri fork()
, exec()
și wait()
au loc și în ce ordine? Justificați.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 */
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 */
exec()
durează mai mult decât apelul fork()
? Justificați.exec
și apelul system
.virtual runtime
și care este valoarea sa inițială? Argumentați de ce este așa.priority inversion
și ilustrați un exemplu.static usize canary = random(); int f(...) { usize value = canary; // if (value != canary) abort (120); else return …; }
pid_t pid; int a = 5; pid = fork(); if (pid == 0) { TODO; }
printf(“%d”, a)
, sau cu șirul vid (nu se execută nicio instrucțiune). Pentru a genera un page fault se poate scrie în memoria procesului, ex. a = 5
(page fault-ul este cauzat de accesarea pentru scriere a unei pagini marcată ca fiind copy-on-write).open
asupra fișierului ce conține biblioteca dinamică, plus apeluri mmap
pentru a face maparea zonelor de fișier în memorie.exit(139)
” (și doar atât), fără a explica ce înseamnă și cum se leagă de subiectul întrebării. Răspunsuri de forma: “numărul de apeluri de sistem este mai mic” fără a aduce și o argumentate/justificare asupra afirmațiilor.read
nu face page fault imediat după fork
deoarece citește date. În general, apelul read citește date dintr-un fișier și le scrie într-un buffer. După fork
, cel mai probabil, o scriere în memorie o să genereze page fault (paginile sunt marcate COW → la scriere se generează page fault → se duplică paginile).Click to display ⇲
Click to hide ⇱
Accesibile pe GitHub, în organizația Open Education Hub, cu deployment prin Docusaurus.
Laboratoare format vechi
Accesibile pe GitHub, în organizația Open Education Hub, cu deployment prin Docusaurus.
Cursuri vechi