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.
01-cow. make și rulați executabilul creat: cow.02-io şi inspectaţi fişierul splice.c. splice?run.sh: sudo ./run.sh
Command terminated by signal 13
03-threads-counter. În ce director din /proc/$PID/ se află informațiile despre thread-urile procesului? De ce acestea au asignat un pid?04-functions-hijacking, compilați (make) și rulați (./test și LD_PRELOAD=./libnative.so ./test. Cum explicați output-ul diferit?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.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?/proc/$PID/maps07-reentr/reentr.c ca fiind reentrante / thread-safe. Puteți modifica programul încât să puneți în evidență aceste aspecte.08-stack-growth.for (i = 0; i < 10; i++) { getpid(); write(1, "A", 1); }
09-syscall.pid_test.c.strace. strace ./pid_test
fork_test.c.SYS_TYPE pe rând valorile SYS_NATIVE şi SYS_GLIBC. *Explicaţi rezultatul obţinut. Citiţi secţiunea NOTES din getpid(2).fork.c din directorul 10-fork./* de completat */
...
fputs("alfa", stderr);
fputs("beta", stdout);
12-file, si rulati comanda ./file >out 2>err
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.int page_size = getpagesize(); for (i = 0; i < 1000; i++) ptr[i] = malloc(page_size);
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?
14-malloc-syscalls.malloc-syscalls.c.make).strace -e brk ./malloc-syscall 2>&1 > /dev/null | wc -l.ltrace -e malloc ./malloc-syscall 2>&1 > /dev/null | wc -l.DO_FREE la valoarea 1.brk au loc? Cum explicați? Ce rol are apelul de sistem brk? char *p;
int status;
size_t i;
int page_size = getpagesize();
char value;
p = mmap(NULL, NUM_PAGES * page_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
for (i = 0; i < NUM_PAGES; i++)
p[i*page_size] = i;
switch (fork()) {
case -1: /* handle error */
perror("fork");
exit(EXIT_FAILURE);
case 0: /* child process */
for (i = 0; i < NUM_PAGES / 2; i++)
value = p[i*page_size];
for (i = NUM_PAGES; i < NUM_PAGES; i++)
p[i*page_size] = page_size-i;
exit(EXIT_SUCCESS);
break;
default:
break;
}
wait(&status);
for (i = 0; i < NUM_PAGES; i++)
p[i*page_size] = i;
15-faults.fork-faults.c.make).sysstat. Pachetul conține utilitarul pidstat care permite monitorizarea page fault-urilor unui proces (prin intermediul argumentului -r).fork-faults. Folosiți ENTER pentru a continua programul.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.