Ossia Frequently Asked Questions.
Su sistemi basati su Unix è disponibile il client SSH che permette di collegarsi in modo sicuro ad una macchina remota su cui abbiamo un account. (Se si utilizza Windows è possible utilizzare il programma Putty, il cui eseguibile e la cui documentazione è disponibile qui).
Una volta aperta la shell è sufficiente digitare il seguente comando:
bash(utente_locale):$ ssh utente@nome_simbolico_o_ip_macchina_remota
e vi verrà richiesta la vostra password per l'utente sulla macchina remota a cui state cercando di collegarvi.
Potete collegarvi al server olivia.cli.di.unipi.it (o a qualsiasi altra macchina del CDC didattica). Usando le vostre credenziali presso il centro di calcolo avrete accesso alla vostra home directory. Ecco come deve fare l'utente rossi a collegarsi al cdc, su olivia:
bash(utente_locale):$ ssh [email protected] Password:la password di rossi
Una volta loggati con successo potete lavorare nella vostra home come fareste se foste loggati ad una macchina dei laboratori, e quindi avendo a disposizione tutti i programmi che vi necessitano: compilatore, debugger, e gli altri tool visti a lezione. Per utilizzare la bash vedere questa Faq. Quando ci si vuole scollegare dalla macchina remota, digitare il comando (sempre nella shell remota):
bash(rossi):$ logout
Sì, ad esempio potreste aver bisogno di utilizzare ddd, o un editor di testo grafico per scrivere i vostri programmi. Per visualizzare l'interfaccia sul vostro display, occorre che vi colleghiate alla macchina usando il comando ssh con opzione -X
bash(utente_locale):$ ssh -X rossi@olivia.cli.di.unipi.it Password:la password di rossi
Dopodichè potete lanciare i vostri programmi da shell nel modo usuale.
Sì, come alla macchina olivia potete collegarvi a qualsiasi macchina del centro di calcolo. Ma è necessario che la macchina sia accesa e vi sia in esecuzione linux, ed in particolare il server ssh. Ricordatevi di impostare i permessi della vostra home directory nel modo opportuno come descritto nella Faq.
Spesso potreste aver bisogno di trasferire file che avete, ad esempio, sulle vostre macchine a casa o sul portatile, verso la vostra home del cdc. A questo scopo potete utilizzare il programa scp:
bash(utente_locale):$ scp file_locale1....file_localeN rossi@olivia.cli.di.unipi.it:./DIRECTORY_REMOTA
Per copiare un intera directory (e tutte le sue sottodirectory) usare l'opzione -r
bash(utente_locale):$ scp -r DIRECTORY rossi@olivia.cli.di.unipi.it:./DIRECTORY_REMOTA
Allo stesso modo è possibile trasferire i file che avete nella vostra home directory remota verso la vostra macchina locale, basta invertire i parametri:
bash(utente_locale):$ scp rossi@olivia.cli.di.unipi.it:./DIRECTORY_REMOTA/file_remoto1 ... rossi@olivia.cli.di.unipi.it:./DIRECTORY_REMOTA/file_remotoN DIRECTORY_LOCALE
Si, e' possibile utilizzando la macro
__LINE__
Si, e' possibile aggiungere campi alle strutture e prototipi nei file .h del primo frammento estendendo la libreria a patto che continuino a funzionare i test del primo frammento.
Si, a patto che i file vengano creati in una directory adeguata (esempio /tmp
), senza sovrascrivere file esistenti e rimossi a fine script (suggerimento: provate man mktemp
)
No, seguendo la convenzione delle funzioni di libreria C gli errori devono essere riportati con un opportuno codice di ritorno ed eventualmente settando errno
. Sara' chi invoca la funzione che invochera` anche perror()
se lo ritiene opportuno.
errno
puo' contenere solo 0 oppure valori definiti dallo standard, vedi
man errno
altrimenti l'output di perror()
e' non significativo.
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
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: 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.