Non esiste un lint
ampiamente utilizzato per Linux, dal momento che
la maggior parte della gente si accontenta degli avvertimenti che
gcc può generare. Probabilmente, quello più utile è il -Wall
opzione che significa 'Warnings, all' ma probabilmente ha un maggior valore
mnemonico, se pensato come qualcosa contro cui si sbatte la testa
(NdT. "wall" in inglese significa "muro").
Esiste un lint di dominio pubblico disponibile su ftp://larch.lcs.mit.edu/pub/Larch/lclint. Putroppo non sono in grado di giudicare la sua validità.
È necessario compilare ed eseguire il link di tutte le sue parti con
l'opzione -g
, e senza -fomit-frame-pointer
. Non è necessario
ricompilarlo interamente, solo le parti di cui si esegue il debug.
Nelle configurazioni a.out le librerie condivise sono compilate con
-fomit-frame-pointer
, con la quale gdb non funzionerà. Questo
perché l'opzione -g
implica un link statico.
Se il linker va in errore fornendo un messaggio che indica
l'impossibilità di trovare libg.a
, significa che non si possiede
/usr/lib/libg.a
, che consiste nella speciale libreria C abilitata
al debugging. Tale libreria può essere fornita nel pacchetto binario
libc, oppure (in versioni di libreria C più recenti) può essere necessario
ottenere il codice sorgente libc ed eseguire personalmente la compilazione.
Tuttavia, è possibile ottenere sufficienti informazioni per la maggior
parte degli scopi semplicemente sostituendola con un collegamento
simbolico con /usr/lib/libc.a
.
Molto software GNU è impostato affinché la compilazione e il link
siano eseguite con l'opzione -g
, che determina la generazione di
eseguibili molto voluminosi (e spesso statici). Questa non è una buona
idea.
Se il programma possiede uno script di configurazione
`autoconf
', è possibile disabilitare le informazioni di
debugging controllando il Makefile
. Naturalmente, se si sta
utilizzando ELF, il link del programma viene eseguito in modo
dinamico indipendentemente dall'impostazione -g
, pertanto si può
semplicemente usare strip
.
Molte persone utilizzano gdb, che può essere ottenuto in forma sorgente
dai siti di archivio GNU
ftp://prep.ai.mit.edu/pub/gnu, oppure in formato binario da
tsx-11 (ftp://tsx-11.mit.edu/pub/linux/packages/GCC) o da
sunsite. xxgdb
è un debugger X basato su gdb (ossia, è
necessario che sia installato gdb). È possibile trovare i sorgenti presso
ftp://ftp.x.org/contrib/xxgdb-1.08.tar.gz.
Rick Sladkey ha eseguito il porting del debugger UPS. Può essere
eseguito anche sotto X, ma a differenza di xxgdb
, non è un semplice
front end X per un debugger basato su testo. Possiede diverse
caratteristiche molto interessanti, e se si ha la necessità di eseguire
diversi debug, è il caso di provarlo. La versione precompilata per
Linux e i patch per i sorgenti UPS possono essere trovati in
ftp://sunsite.unc.edu/pub/Linux/devel/debuggers/, mentre i
sorgenti originali in
ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z.
Un altro strumento utile per il debug è 'strace
', che
visualizza le chiamate di sistema fatte da un processo. Questo strumento
possiede anche molti altri utilizzi, inclusa la possibilità di sapere
i nomi di file compilati, di cui non si possiede il sorgente; di esasperare
i race condition in programmi che si sospettano contenerle, e in
generale di imparare come funzionano le cose. La versione più recente
di strace
(attualmente la 3.0.8) può essere trovata in
ftp://ftp.std.com/pub/jrs/.
I programmi demone tipicamente eseguono presto la fork()
, e
terminano il programma chiamante. Questo rende la sessione di debug
molto breve.
Il modo più semplice per aggirare questo ostacolo consiste nell'impostare
un breakpoint per fork
, e quando il programma si blocca, forzare
la restituzione di 0.
(gdb) list
1 #include <stdio.h>
2
3 main()
4 {
5 if(fork()==0) printf("child\n");
6 else printf("parent\n");
7 }
(gdb) break fork
Breakpoint 1 at 0x80003b8
(gdb) run
Starting program: /home/dan/src/hello/./fork
Breakpoint 1 at 0x400177c4
Breakpoint 1, 0x400177c4 in fork ()
(gdb) return 0
Make selected stack frame return now? (y or n) y
#0 0x80004a8 in main ()
at fork.c:5
5 if(fork()==0) printf("child\n");
(gdb) next
Step singolo fino all'uscita dalla funzione fork,
che non contiene informazioni sul numero di riga.
child
7 }
Quando Linux viene avviato, solitamente è configurato per non produrre
core file. Se si desidera, è possibile utilizzare il comando
interno dell'interprete comandi per riabilitarli: per shell
compatibili C (come tcsh
) corrisponde al comando
% limit core unlimited
mentre per interpreti comandi di tipo Bourne (sh
, bash
, zsh
,
pdksh
) utilizzare
$ ulimit -c unlimited
Se si desidera una maggiore flessibilità nell'assegnazione dei nomi ai
core file (nel caso, per esempio, di analisi post-mortem con
un debugger che contiene errori) è possibile eseguire una piccola
modifica al proprio kernel. Cercare in fs/binfmt_aout.c
e
fs/binfmt_elf.c
il codice tipo:
memcpy(corefile,"core.",5); #if 0 memcpy(corefile+5,current->comm,sizeof(current->comm)); #else corefile[4] = '\0'; #endif
e modificare gli 0
in 1
.
Il profiling rappresenta un modo per esaminare le parti di un
programma richiamate più frequentemente o eseguite più a lungo. È buona
norma ottimizzare il codice e vedere dove viene perso del tempo. È
necessario compilare tutti i file oggetto sui quali si desiderano
informazioni sul tempo di esecuzione con l'opzione -p
, e per
interpretare il file di output sarà necessario anche gprof
(dal pacchetto binutils). Si veda la pagina di manuale gprof
per ulteriori dettagli.