[Tech] OT - Programmazione C

Marco Ermini markoer@usa.net
Sab 21 Feb 2004 23:18:05 CET


On Sat, 21 Feb 2004 17:01:55 +0100, Valerio Montagnani <tech@vmontagnani.it>
wrote:

[...]
> che cosa significa core dump?

I processi in Unix comunicano fra loro e con il kernel tramite "segnali".

Quando un'applicazione termina può farlo in seguito a vari segnali; alcuni
di essi - per default quelli più "violenti" come SIGABRT = abnormal
termination, cioé abort, o SIGBUS o SIGEMT = problema hardware (sul PDP-11
c'era l'istruzione "emulator trap" da cui viene il segnale SIGEMT...), o
appunto SIGSEV = indirizzamento ad un'area di memoria non valida ecc. -
hanno come azione di default "terminate w/core", ovvero il processo esce
generando su disco un file che contiene un'immagine di memoria del processo
che era in esecuzione.

Questo file viene in genere scritto su disco col nome "core"; non viene
generato se non si hanno i permessi di scrittura su quella directory, se il
programma era stato eseguito suid o sugid, o se la dimensione del file core
supera il limite di RLIMIT_CORE (impostabile su Linux come diceva Franco).

FreeBSD (e tutti i BSD dal 4.3 in su) fa una cosa in più di Linux in quanto
genera il file chiamandolo core.prog dove prog è composto dai primi 16
caratteri del nome del processo che era in esecuzione.

Il file di core può essere caricato con molti debugger per ricostruire dove
il programma ha fallito, attraverso l'esame dello stato in cui si trovava il
processo nel momento in cui è terminato. Con alcuni debugger puoi anche
rieseguire il processo facendolo ripartire dallo stato in cui era al momento
del core.


> > Bisogna anche tenere presente che a volte si usa il "copy on write"  
> > (sempre per velocizzare), per cui se per esempio hai fatto un fork e poi
> > che ci trova qualcosa di sensato.
> 
> che cosa è un fork?

E' una chiamata di sistema standard di Unix attraverso cui un processo si
"duplica". Per semplicità, immaginati che al momento del fork l'area di
memoria che contiene il processo in esecuzione venga duplicata (più che il
codice, l'area che contiene le variabili); la copia, che è un figlio, girerà
eseguendo lo stesso codice del padre (è lo stesso programma duplicato!)
ripartendo dall'istruzione successiva al fork ed andando in esecuzione in
parallelo al padre.

Un buon esempio è quello che ti ha fatto Franco con Apache, che si duplica
in enne processi per rispondere alle richieste dei client. In pratica
Apache ed i programmi come lui usano un metodo simile a questo:

if ((pid=fork())<0) {
    printf ("errore fork");
    exit (-1);
}
else if (pid == 0) { /* sono il child */
    printf ("I am the child...");
    exit (127);
}
if ((pid == waitpid (pid, &status, 0)) < 0) /* I am the father */
    printf ("waitpid error");
exit (0);

La "printf ("I am the child...")" è eseguita solo se sei il figlio. In
questo modo puoi far partire tanti processi da un solo padre e far loro fare
quello che ti serve.

Il "copy on write" è un'ottimizzazione: in Unix i processi sono generalmente
composti da codice rientrante, ovvero da codice che può avere un'unica
immagine eseguibile di runtime anche quando è eseguita varie volte; quindi,
dato che l'operazione più "costosa" in termini di risorse su Unix è proprio
la copia del processo nel momento della fork (pensa che deve essere
duplicata tutta la parte runtime, gli stack, lo heap dell variabili ecc.)
allora in genere gli Unix ottimizzano la fork facendo in modo che la copia
non venga eseguita se non ce n'è bisogno (ovvero quando la memoria viene
solo letta: infatti finché è uguale sia per il padre che per il figlio non
c'è bisogno di duplicarla, come ti puoi benissimo immaginare!), ma solo nel
momento in cui uno dei processi scrive per cambiarla. Per questo si chiama
"copy on write", perché la copia effettiva della memoria viene eseguita solo
in seguito ad una scrittura.

I singoli Unix poi hanno maniere molto diverse di affrontare la cosa.

Per ulteriori approfondimenti, io tengo dei corsi di Unix e di
programmazione C e C++, dalle cui dispense ho preso questi paragrafi ;-)


ciao
-- 
Marco Ermini
http://macchi.markoer.org - ICQ 50825709 - GPG KEY 0x64ABF7C6 - L.U. #180221
Perche' perdere tempo ad imparare quando l'ignoranza e' istantanea? (Hobbes)
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        non disponibile
Tipo:        application/pgp-signature
Dimensione:  189 bytes
Descrizione: non disponibile
URL:         <http://lists.linux.it/pipermail/flug-tech/attachments/20040221/8b88a9b6/attachment.pgp>


Maggiori informazioni sulla lista flug-tech