Ossia Frequently Asked Questions.
Si, un modo semplice per gestiore i timeout per l'aggiornamento dell'albero e' integrarli con la gestione dei segnali usando un thread apposito e la funzione sigtimedwait(). Con questa funzione e' possibile settare un timeout pari a K sec. Se la funzione ritorna -1 errno==EAGAIN il timeout e' trascorso senza l'arrivo di segnali (quindi si puo' ricostruire l'albero) altrimenti il valore ritirnato e' il sagnale arrivato (vedi man sigtimedwait).
Nella descrizione c'e' un errore di stampa che chiede di usare i socket AF_INET per comunicare fra server e client. Si tratta di un errore di stampa in quanto nel progetto devono essere usati esclusivamente i socket AF_UNIX.
"CN4456K 12/12/2008-13:30 13/12/2008-14:30", /* alfanumerico */
Le targhe sono composte da due caratteri maiuscoli, tre cifre e altri due caratteri maiuscoli, quindi il penultimo carattere della targa non puo' essere 6.
Si, se la removePerm()
cancella l'ultimo permesso il nodo non fornisce piu' informazione e deve essere rimosso e deallocato.
Usando una distribuzione Linux recente (ad esempio Ubuntu 8.04, 8.10, o comunque distribuzioni che forniscaono bash in versione 3.2 o superiore) lo script di debugging bashdb non funziona. Fortunatamente le stesse distribuzioni forniscono lo script gia` pacchettizzato in una versione aggiornata. Ad esempio, per installarlo sotto Ubuntu o Debian basta dare il comando
sudo aptitude install bashdb
quindi lanciarlo normalmente con
bashdb nome_script
(vedete anche man bashdb e l'help che ottenete digitando “h” al suo prompt).
E` possibile usare GDB per debuggare programmi multiprocesso / multithread come indicato nella documentazione qui e qui. E` possibile usare i comandi indicati anche in DDD, scrivendoli manualmente nel prompt del GDB in basso nella schermata.
E' possibile usare il debugger GDB da emacs. Questo permette di seguire interattivamente il flusso di esecuzione in due sottofinestre dell'editor. Per attivarlo:
ESC-X gdb
e fornendo il nome dell'eseguibile da debuggare (a questo punto si attiva una finestra GDB in cui e' possibile fornire gli usuali comandi)R: Questa situazione si puo` verificare per tre ragioni differenti:
-g
);g++
);libc
, libm
…).
Quest'ultima situazione si verifica nel caso in cui siano state usate funzioni di libreria all'interno delle quali viene allocata della memoria (come la strdup()
). La memoria, anche se allocata da funzioni di libreria, deve essere sempre liberata usando una free()
.
char *p; char s[6] = "pippo"; p = strdup(s); /* ... */ free(p);
R: Molto probabilmente la causa di buona parte dei problemi di quota e` dovuta all'utilizzo di eclipse come ambiente di sviluppo. la prima cosa da fare e` vedere quanto spazio e` utilizzato inutilmente da eclipse. (si assume che l'utente lavori nella directory workspace)
(susanna):==>du -sh ~/workspace/.metadata 12.4M /home/susanna/workspace/.metadata
a questo punto si puo` procedere con l'eliminazione. ATTENZIONE: state attenti ad inserire questo comando esattamente cosi`, altrimenti rischiate di cancellare tutti i vostri files
(susanna):==>rm -fr ~/workspace/.metadata
Oppure
Si puo' cancellare la cache di Mozilla mediante l' utilizzo dello script rimuovicache.sh fornito dai docenti:
(susanna):==> wget http://www.cli.di.unipi.it/~bartolin/rimuovicache.sh (susanna):==> chmod +x rimuovicache.sh (susanna):==> ./rimuovicache.sh
Oppure:
(susanna):==> ./rimuovicache.sh --help
Per un mostrare le opzioni dello script.
R: Molto probabilmente e' stata raggiunta la quota disco. Per risolvere il problema e' sufficiente digitare [CTL+ALT+F1], effettuare il login in modo testuale e seguire i passi della FAQ “ho la quota disco piena e non riesco a salvare i miei files”.
R: Per ragioni “storiche” il CDC usa la csh/tcsh come shell default di login e non permette di cambiarla. Nel prossimo futuro verra' effettuato un adeguamento allo standard di fatto attuale fornendo la bash come shell di login e permettendo a chi non ce l'ha di sceglierla. Per sperimentare con la shell bash basta digitare
(susanna):==> bash bash-2.05b$
oppure
(susanna):==> exec bash bash-2.05b$
in entrambi i casi la vostra shell mandera' in esecuzione una bash con cui potrete interagire. Alla fine potete uscire con
bash-2.05b$ exit exit (susanna):==>
oppure EOF (CTRL-D).
Per non avere un ambiente “nudo” si consiglia di salvare i seguanti script di configurazione (esattamente con questi nomi) nella vostra home directory (ad esempio, ~susanna/ per l'utente susanna):
.bashrc .bash_profile .bash_aliases
In questo modo otterrete un prompt piu' significativo e un ambiente piu` gradevole:
(susanna):==> bash susanna@aulaa:~$
In particolare aggiungendo ulteriori comandi di alias al terzo script potete personalizzare la shell creandovi i vostri alias usuali per i vari comandi (es, “rm -i” per “rm”, o “h” per “history”).
NOTA BENE: I sistemisti sconsigliano vivamente di mettere il comando exec bash
direttamente nei file .login o .cshrc perche' questo potrebbe interferire negativamente con altri settaggi standard dei vostri ambienti, in particolare quello grafico.
nella directory che lo contiene ma il risultato e' stato
bash: a.out command not found
R: La variabile di ambiente ambiente PATH non contiene la directory corrente (“.”): per eseguire il programma basta fornire il parth name completo dell'eseguibile, ad esempio quello relativo:
$ ./a.out
Per risolvere il problema si deve aggiungere la directory corrente alla variabile PATH della shell, nella bash basta dare il comando:
$ export PATH=$PATH:.
o nella csh/tcsh
% setenv PATH ${PATH}:.
Per vedere il valore del PATH
$ echo $PATH
per capire che shell stiamo utilizzando
$ echo $SHELL
Per non dover ripetere il comando export/setenv ogni volta che aprite una finestra dovrebbe essere sufficiente aggiungere il comando come una riga dello script ~/.bashrc (bash) o ~/.cshrc (csh/tcsh).
R: Usando le sezioni 2 e 3 dei manuali, rispettivamente per system calls e funzioni di libreria, ad esempio
$ man 2 read $ man 3 printf
R: Basta fissare un nome di directory noto solo agli utenti del gruppo (es 56yu897j) e proteggere in lettura la directory che la contiene in modo che solo chi ne conosce il nome possa accedervi. Ad esempio
$ chmod 711 ~ (*tolgo i diritti di lettura della mia home a tutti eccetto me*) $ ls -ld ~ drwx--x--x 8 susanna user 672 2005-04-12 16:48 /home/susanna/ $ mkdir ~/56yu897j (*creo la directory segreta*)
Adesso per gli altri utenti e' impossibile fare ls sulla mia home directory es:
$ echo $USER (* sono l'utente garibaldi*) garibaldi $ ls ~susanna ls: /home/susanna/: Permission denied
Pero' posso ancora accedere alla directory 56yu897j se ne conosco il nome
$ echo $USER (* sono l'utente garibaldi*) garibaldi $ ls ~susanna/56yu897j prorub/
R: Questo e' un tipico sintomo di errori nell'allocazione delle stringhe (spazio insufficiente), buffer overrun (come effetto spesso di strcpy() o di altre funzioni che assumono di lavorare su stringhe terminate correttamente se invocate su stringhe senza terminatore), oppure di errata gestione e copia dei puntatori.
Quindi la manifestazione spesso non ha niente a che vedere con il punto in cui si e' verificato l'errore vero e proprio.
In questo caso la cosa da fare e' ricontrollare incrementalmente tutto il codice (magari con l'aiuto di un debugger) alla ricerca di possibili malfunzionamenti su stringhe e puntatori.
R: E' possibile usare il comando indent (vedi la sua pagina di manuale per tutte le opzioni) per indentare automaticamente il codice: una buona linea di comando e'
indent -kr -br -brs file.c
Su Vim l'indentazione puo' essere fatta tramite il comando =
R: Molto brevemente: il testing del codice non va confuso con il debugging (ovvero la ricerca dell'errore in un programma che si ritiene sbagliato). Infatti nel testing si cerca di mettere sotto pressione un codice in principio corretto in modo da evidenziare tempestivamente possibili malfunzionamenti.
E' buona norma testare sistematicamente i vari aspetti delle funzioni man mano che queste vengono sviluppate. In particolare e' una buona idea sviluppare, parallelamente al codice, un programma di test che stressa i punti importanti e controlla automaticamente che i risultati siano corretti.
In particolare, e' una PESSIMA idea iniziare a testare il codice dopo averne scritta gran parte. Il testing deve essere fatto incrementalmente su ogni funzione sviluppata. Questo permette di trovare piu' semplicemente gli errori perche' e' possibile concentrarsi su porzioni piu' piccole e ben definite del programma.
E' anche una buona norma raccogliere tutti i test che verificano le varie funzioni in modo da ripeterli automaticamente (con opportuni script) ogni volta che il codice viene modificato per fissare un nuovo bug o aggiungere nuove funzionalita' su una funzione gia' testata.
In rete esistono librerie che aiutano ad organizzare i test (vedi ad esempio C unit e gcov o man gcov per controllare quale parte del codice e' stata testata e quale no). Per una trattazione piu' dettagliata ma introduttiva vedi ad esempio Kerninghan & Pike capitolo 6.
R: Una possibile struttura della relazione e' la seguente:
R: Su alcune architetture la accept() va invocata con
struct sockaddr_un addr; int ret; socklen_t x2 = sizeof (addr); ret = accept(s, (struct sockaddr *)&addr, &x2);
invece che passando il secondo argomento NULL.