Indice
Vengono forniti in questo capitolo alcune informazioni base da cui partire per imparare a programmare su un sistema Debian abbastanza da seguire il codice sorgente impacchettato. Quello che segue è un elenco dei pacchetti importanti per la programmazione e dei corrispettivi pacchetti di documentazione.
Tabella 12.1. Elenco di pacchetti di aiuto per la programmazione
pacchetto | popcon | dimensione | documentazione |
---|---|---|---|
autoconf *
|
V:4, I:25 | 2256 |
"info autoconf " fornito da
autoconf-doc
|
automake *
|
V:3, I:21 | 1812 |
"info automake " fornito da
automake1.10-doc
|
bash
*
|
V:91, I:99 | 3536 |
"info bash " fornito da bash-doc
|
bison
*
|
V:2, I:15 | 1504 |
"info bison " fornito da bison-doc
|
cpp
*
|
V:38, I:82 | 32 |
"info cpp " fornito da cpp-doc
|
ddd
*
|
V:0.3, I:2 | 3852 |
"info ddd " fornito da ddd-doc
|
exuberant-ctags *
|
V:1.2, I:5 | 284 |
exuberant-ctags (1)
|
flex
*
|
V:2, I:15 | 1352 |
"info flex " fornito da flex-doc
|
gawk
*
|
V:28, I:32 | 2172 |
"info gawk " fornito da gawk-doc
|
gcc
*
|
V:17, I:67 | 28 |
"info gcc " fornito da gcc-doc
|
gdb
*
|
V:4, I:22 | 4812 |
"info gdb " fornito da gdb-doc
|
gettext *
|
V:8, I:46 | 7272 |
"info gettext " fornito da gettext-doc
|
gfortran *
|
V:0.9, I:6 | 8 |
"info gfortran " fornito da
gfortran-doc (Fortran 95)
|
gpc
*
|
V:0.07, I:0.5 | 8 |
"info gpc " fornito da gpc-doc (Pascal)
|
fpc
*
|
I:0.4 | 40 |
fpc (1) e html forniti da fp-docs
(Pascal)
|
glade
*
|
V:0.3, I:2 | 1652 | aiuto fornito attraverso menu (compilatore UI) |
glade-gnome *
|
V:0.09, I:1.2 | 508 | aiuto fornito attraverso menu (compilatore UI) |
libc6
*
|
V:97, I:99 | 10012 |
"info libc " fornito da glibc-doc e
glibc-doc-reference
|
make
*
|
V:21, I:72 | 1220 |
"info make " fornito da make-doc
|
xutils-dev *
|
V:1.7, I:15 | 1728 |
imake (1), xmkmf (1), ecc.
|
mawk
*
|
V:66, I:99 | 244 |
mawk (1)
|
perl
*
|
V:88, I:99 | 18528 |
perl (1) e pagine html forniti da
perl-doc e perl-doc-html
|
python *
|
V:62, I:97 | 736 |
python (1) e pagine html forniti da
python-doc
|
tcl8.4 *
|
V:8, I:46 | 3332 |
tcl (3) e pagine dettagliate del manuale forniti da
tcl8.4-doc
|
tk8.4
*
|
V:5, I:34 | 2712 |
tk (3) e pagine dettagliate di manuale forniti da
tk8.4-doc
|
ruby
*
|
V:9, I:24 | 120 |
ruby (1) e guida interattiva di riferimento forniti da
ri
|
vim
*
|
V:15, I:33 | 1792 |
menu di aiuto(F1) fornito da vim-doc
|
susv2
*
|
I:0.03 | 48 | scarica le specifiche "The Single Unix Specifications v2" |
susv3
*
|
I:0.07 | 48 | scarica le specifiche "The Single Unix Specifications v3" |
Guide di riferimento in linea sono disponibili digitando "man
nome
" dopo aver installato i pacchetti manpages
e manpages-dev
. Le guide di riferimento in linea per gli
strumenti GNU sono disponibili digitando "info
nome_programma
", dopo aver installato i pertinenti pacchetti di
documentazione. Può essere necessario includere gli archivi
"contrib
e non-free
, oltre
all'archivio main
, dato che alcune documentazioni GFDL
non sono considerate conformi alle DFSG.
![]() |
Avvertimento |
---|---|
Non usare " |
![]() |
Attenzione |
---|---|
I programmi software compilati direttamente dai sorgenti andrebbero
installati in " |
![]() |
Suggerimento |
---|---|
Esempi di codice per creare la "Canzone 99 bottiglie di birra" dobrebbe dare una buona idea di praticamente tutti i linguaggi di programmazione. |
Uno script di shell è un file di testo con il bit di esecuzione impostato e contiene i comandi nel formato seguente.
#!/bin/sh ... righe di comando
La prima riga specifica l'interprete di shell che legge ed esegue il contenuto di questo file.
Leggere script di shell è il modo migliore per capire come funzioni un sistema *nix. In questa sezione vengono forniti alcune nozioni di riferimento e promemoria per la programmazione di shell. Vedere "Errori in shell" (http://www.greenend.org.uk/rjk/2001/04/shell.html) per imparare dagli errori.
A differenza della modalità interattiva della shell (vedere Sezione 1.5, «Il semplice comando di shell» e Sezione 1.6, «Elaborazione di testo stile Unix»), gli script di shell usano spesso parametri, costrutti condizionali e cicli.
Molti script di sistema possono essere interpretati da una qualsiasi delle
shell POSIX (vedere Tabella 1.13, «Elenco di programmi shell»). La shell predefinita per il sistema è
"/bin/sh
" che è un collegamento simbolico che punta al
programma reale.
bash
(1) per lenny
o precedenti
dash
(1) per squeeze
o successivi
Evitare di scrivere uno script di shell con bashismi o zshismi per renderlo portabile tra tutte le shell
POSIX. Si può controllare uno script con
checkbashisms
(1).
Tabella 12.2. Elenco di bashismi tipici
Buono: POSIX | Da evitare: bashismo |
---|---|
if [ "$pippo" = "$pluto" ] ; then …
|
if [ "$pippo" == "$pluto" ] ; then …
|
diff -u file.c.orig file.c
|
diff -u file.c{.orig,}
|
mkdir /pippopluto /pippopaperino
|
mkdir /pippo{pluto,paperino}
|
nomefunzione() { … }
|
function nomefunzione() { … }
|
formato ottale: "\377 "
|
formato esadecimale: "\xff "
|
Il comando "echo
" deve essere usato con le precauzioni
seguenti dato che la sua implementazione è diversa negli svariati comandi
interni della shell ed esterni.
-e
" e
"-E
".
-n
".
![]() |
Nota |
---|---|
Sebbene l'opzione " |
![]() |
Suggerimento |
---|---|
Se è necessario inserire sequenze di escape nella stringa in output, usare
il comando " |
Negli script di shell vengono spesso usati parametri speciali.
Tabella 12.3. Elenco di parametri di shell
parametro di shell | valore |
---|---|
$0
|
nome della shell o dello script di shell |
$1
|
primo (1) argomento di shell |
$9
|
nono (9) argomento di shell |
$#
|
numero di parametri posizionali |
"$*"
|
"$1 $2 $3 $4 … "
|
"$@"
|
"$1" "$2" "$3" "$4" …
|
$?
|
stato d'uscita del comando più recente |
$$
|
PID dello script di shell |
$!
|
PID del compito sullo sfondo avviato più recentemente |
Le nozioni base da ricordare riguardanti la espansione dei parametri sono le seguenti.
Tabella 12.4. Elenco di espansioni di parametri di shell
forma della espressione con parametri |
valore se var è impostata
|
valore se var non è impostata
|
---|---|---|
${var:-stringa}
|
"$var "
|
"stringa "
|
${var:+stringa}
|
"stringa "
|
"null "
|
${var:=stringa}
|
"$var "
|
"stringa " (ed esegue "var=stringa ")
|
${var:?string}
|
"$var "
|
invia con echo "stringa " allo stderr (ed esce con stato di errore)
|
I due punti ":
" in tutti gli operatori nell'elenco
precedente sono di fatto opzionali.
:
" l'operatore =
controlla che il suo operando esista e
sia non nullo
:
" l'operatore
= controlla solo che il suo operando esista
Tabella 12.5. Elenco di sostituzioni chiave di parametri di shell
forma della sostituzione di parametri | risultato |
---|---|
${var%suffisso}
|
rimuove il più piccolo modello di suffisso |
${var%%suffisso}
|
rimuove il più grande modello di suffisso |
${var#prefisso}
|
rimuove il più piccolo modello di prefisso |
${var##prefisso}
|
rimuove il più grande modello di prefisso |
Ogni comando resiituisce uno stato di uscita che può essere usato in costrutti condizionali.
![]() |
Nota |
---|---|
"0" nel contesto condizionale della shell significa "Vero", mentre "0" nel contesto condizionale in C significa "Falso". |
![]() |
Nota |
---|---|
" |
Le espressioni condizionali di base che è bene ricordare sono le seguenti.
<comando> &&
<se_successo_esegue_anche_questo_comando> || true
"
<comando> ||
<se_non_successo_esegue_anche_questo_comando> || true
"
if [ <espressione_condizionale> ]; then <se_successo_esegue_questo_comando> else <se_non_successo_esegue_questo_comando> fi
In questo caso il "|| true
" finale era necessario per
assicurare che lo script non termini accidentalmente a tale riga quando la
shell è invocata con l'opzione "-e
".
Tabella 12.6. Elenco di operatori per paragonare file in espressioni condizionali
equazione | condizione perché venga restituito il valore logico "vero" |
---|---|
-e <file>
|
<file> esiste |
-d <file>
|
<file> esiste ed è una directory |
-f <file>
|
<file> esiste ed è un file regolare |
-w <file>
|
<file> esiste ed è scrivibile |
-x <file>
|
<file> esiste ed è eseguibile |
<file1> -nt <file2>
|
<file1> è più recente di <file2> (data di modifica) |
<file1> -ot <file2>
|
<file1> è più vecchio di <file2> (data di modifica) |
<file1> -ef <file2>
|
<file1> e <file2> sono sullo stesso device e stesso numero inode |
Tabella 12.7. Elenco di operatori per paragonare stringhe in espressioni condizionali
equazione | condizione perché venga restituito il valore logico "vero" |
---|---|
-z <str>
|
la lunghezza di <str> è zero |
-n <str>
|
la lunghezza di <str> è diversa da zero |
<str1> = <str2>
|
<str1> e <str2> sono uguali |
<str1> != <str2>
|
<str1> e <str2> non sono uguali |
<str1> < <str2>
|
se ordinate, <str1> viene prima di <str2> (dipendente dalla localizzazione) |
<str1> > <str2>
|
se ordinate, <str1> viene dopo di <str2> (dipendente dalla localizzazione) |
Gli operatori aritmetici di comparazione
di interi nelle espressioni condizionali sono "-eq
",
"-ne
", "-lt
",
"-le
", "-gt
" e
"-ge
".
Ci sono diverse espressioni per cicli usaili nella shell POSIX.
for x in pippo1 pippo2 … ; do comando ; done
" ripete il
ciclo assegnando gli elementi nell'elenco "pippo1 pippo2
…
" alla variabile "x
" ed eseguendo
"comando
".
while condizione ; do comando ; done
" ripete
"comando
" fintanto che "condizione
" è
vera.
until condizione ; do comando ; done
" ripete
"comando
" fintanto che "condition
" è
non vera.
break
" permette di uscire dal ciclo.
continue
" permette di riprendere dalla successiva
iterazione del ciclo.
![]() |
Suggerimento |
---|---|
L'iterazione numerica in stile linguaggio C può
essere realizzata usando |
![]() |
Suggerimento |
---|---|
Vedere Sezione 9.5.9, «Ripetere un comando su diversi file». |
A grandi linee la shell elabora uno script nel modo seguente.
"…"
o
'…'
.
La shell spezza le altre parti della riga in elementi in base ai caratteri seguenti.
<spazio> <tabulazione> <a
capo>
< > | ; & ( )
La shell controlla, per ciascun elemento non racchiuso tra
"…"
o '…'
, la presenza di parole riservate per regolare il proprio
comportamento.
if then elif
else fi for in while unless do done case esac
"…"
o '…'
.
La shell espande il carattere tilde se
non è racchiuso in "…"
o '…'
.
~
" → directory home dell'utente attuale
~<utente>
" → directory home di
<utente>
La shell espande parametri nei loro
valori, se non sono racchiusi in '…'
.
$PARAMETRO
" o "${PARAMETRO}
"
La shell espande sostituzioni di comandi,
se non sono racchiuse in '…'
.
$( comando )
" → output di "comando
"
` command `
" → output di "comando
"
La shell espande glob di nomi percorso
nei nomi di file corrispondenti, se non sono racchiusi in
"…"
o '…'
.
*
→ qualsiasi carattere
?
→ un carattere
[…]
→ uno qualunque dei caratteri in
"…
"
La shell cerca comando tra le cose seguenti e lo esegue.
$PATH
"
Virgolette singole all'interno di virgolette doppie non hanno alcun effetto.
L'esecuzione di "set -x
" nella shell o l'invocazione
della shell con l'opzione "-x
" fanno sì che la shell
stampi tutti i comandi eseguiti. Ciò è piuttosto utile per il debug.
Per far sì che il proprio programma di shell sia il più portabile possibile tra i sistemi Debian, è una buona idea limitare i programmi di utilità a quelli forniti dai pacchetti essenziali.
aptitude search ~E
" elenca i pacchetti essenziali.
dpkg -L <nome_pacchetto> |grep '/man/man.*/'
"
elenca le pagine man per i comandi forniti dal pacchetto
<nome_pacchetto>
.
Tabella 12.8. Elenco di pacchetti contenenti piccoli programmi di utilità per script di shell
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
coreutils *
|
V:92, I:99 | 13828 | Utilità GNU di base |
debianutils *
|
V:93, I:99 | 260 | utilità varie specifiche di Debian |
bsdmainutils *
|
V:81, I:99 | 768 | raccolte di ulteriori utilità da FreeBSD |
bsdutils *
|
V:77, I:99 | 196 | utilità di base per 4.4BSD-Lite |
moreutils *
|
V:0.3, I:1.5 | 220 | utilità Unix aggiuntive |
![]() |
Suggerimento |
---|---|
Sebbene |
L'interfaccia utente di un semplice programma shell può essere migliorata
dalla banale interazione con i comandi echo
e
read
ad una più interattiva con l'uso dei cosiddetti
programmi di dialogo ecc.
Tabella 12.9. Elenco di programmi per interfaccia utente
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
x11-utils *
|
V:26, I:53 | 652 |
xmessage (1): mostra un messaggio o richiesta in una
finestra (X)
|
whiptail *
|
V:42, I:99 | 104 | mostra riquadri di dialogo amichevoli da script di shell (newt) |
dialog *
|
V:4, I:25 | 1592 | mostra riquadri di dialogo amichevoli da script di shell (ncurses) |
zenity *
|
V:8, I:41 | 4992 | mostra riquadri di dialogo grafici da script di shell (gtk2.0) |
ssft
*
|
V:0.01, I:0.11 | 152 | Shell Scripts Frontend Tool, strumento per frontend per script di shell (contenitore per zenity, kdialog, e dialog con gettext) |
gettext *
|
V:8, I:46 | 7272 |
"/usr/bin/gettext.sh ": traduce messaggi
|
Questo è un semplice script che crea un'immagine ISO con dati RS02 forniti
da dvdisaster
(1).
#!/bin/sh -e # gmkrs02 : Copyright (C) 2007 Osamu Aoki <osamu@debian.org>, Public Domain #set -x error_exit() { echo "$1" >&2 exit 1 } # Inizializza le variabili DATA_ISO="$HOME/Desktop/iso-$$.img" LABEL=$(date +%Y%m%d-%H%M%S-%Z) if [ $# != 0 ] && [ -d "$1" ]; then DATA_SRC="$1" else # Seleziona la directory per creare l'immagine ISO dalla cartella sul desktop DATA_SRC=$(zenity --file-selection --directory \ --title="Seleziona la radice dell'albero di directory per creare l'immagine ISO") \ || error_exit "Uscita durante la selezione della directory" fi # Controlla la dimensione dell'archivio xterm -T "Controllo dimensione $DATA_SRC" -e du -s $DATA_SRC/* SIZE=$(($(du -s $DATA_SRC | awk '{print $1}')/1024)) if [ $SIZE -le 520 ] ; then zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="La dimensione dei dati va bene per un CD di backup:\\n $SIZE MB" elif [ $SIZE -le 3500 ]; then zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="La dimensione dei dati va bene per un DVD di backup:\\n $SIZE MB" else zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="Dimensione dei dati troppo grande per farne il backup: $SIZE MB" error_exit "Dimensione dei dati troppo grande per farne il backup :\\n $SIZE MB" fi # solo xterm sicuramente ha un'opzione -e funzionante # Crea immagine raw ISO rm -f "$DATA_ISO" || true xterm -T "genisoimage $DATA_ISO" \ -e genisoimage -r -J -V "$LABEL" -o "$DATA_ISO" "$DATA_SRC" # Crea dati ridondanti RS02 supplementari xterm -T "dvdisaster $DATA_ISO" -e dvdisaster -i "$DATA_ISO" -mRS02 -c zenity --info --title="Dvdisaster RS02" --width 640 --height 400 \ --text="dati ISO/RS02 ($SIZE MB) \\n creati per: $DATA_ISO" # EOF
Si potrebbe voler creare un lanciatore sul desktop con un comando definito
in modo simile a "/usr/local/bin/gmkrs02 %d
".
Make è un'utilità per mantenere gruppi di
programmi. Quando make
(1) viene eseguito legge il file di
regole, "Makefile
" e aggiorna il file target se dipende
da file prerequisiti che sono stati modificati dall'ultima volta che esso
stesso è stato modificato oppure se il file target non esiste. L'esecuzione
di questi aggiornamenti può avvenire in modo concorrente.
La sintassi del file di regole è la seguente.
target: [ prerequisiti ... ] [TAB] comaando1 [TAB] -comando2 # ignora errori [TAB] @comando3 # sopprime echo
Qui " [TAB]
è il codice di TAB. Ciascuna riga è
interpretata dalla shell dopo la sostituzione delle variabili di make. Usare
"\
" alla fine di una riga per continuare lo script. Usare
"$$
" per inserire "$
" per valori di
ambiente per uno script di shell.
Regole implicite per il target ed i prerequisiti possono essere scritte, per esempio, nel modo seguente.
%.o: %.c header.h
In questo caso il target contiene il carattere "%
"
(esattamente un carattere). Il "%
" fa corrispondenza con
qualsiasi sottostringa non vuota nei nomi di file dei target
effettivi. Similmente i prerequisiti usano "%
" per
mostrare come i loro nomi trovino corrispondenza nei nomi dei target
effettivi.
Tabella 12.10. Elenco di variabili automatiche di make
variabile automatica | valore |
---|---|
$@
|
target |
$<
|
primo prerequisito |
$?
|
tutti i prerequisiti più recenti |
$^
|
tutti i prerequisiti |
$*
|
"% " nome base con corrispondenza con il modello target
|
Tabella 12.11. Elenco di espansioni delle variabili di make
espansione di variabile | descrizione |
---|---|
pippo1 := pluto
|
espansione valida una volta sola |
pippo2 = pluto
|
espansione ricorsiva |
pippo3 += pluto
|
accoda |
Eseguire "make -p -f/dev/null
" per vedere le regole
interne automatiche.
Si può impostare l'ambiente appropriato per compilare programmi scritti nel linguaggio di programmazione C nel modo seguente.
# apt-get install glibc-doc manpages-dev libc6-dev gcc build-essential
Il pacchetto libc6-dev
, cioè la libreria GNU C, fornisce
la libreria standard C che è una
raccolta di file header e routine di libreria usati dal linguaggio di
programmazione C.
Vedere come documenti di riferimento per C i seguenti.
info libc
" (documento di riferimento per le funzioni
della libreria C)
gcc
(1) e "info gcc
"
ogni_nome_di_funzione_della_libreria_C
(3)
Un semplice esempio "esempio.c
" può essere compilato con
una libreria "libm
" in un eseguibile
"eseg_esempio
" nel modo seguente.
$ cat > esempio.c << EOF #include <stdio.h> #include <math.h> #include <string.h> int main(int argc, char **argv, char **envp){ double x; char y[11]; x=sqrt(argc+7.5); strncpy(y, argv[0], 10); /* previeni buffer overflow */ y[10] = '\0'; /* riempi per assicurare che la stringa finisca con '\0' */ printf("%5i, %5.3f, %10s, %10s\n", argc, x, y, argv[1]); return 0; } EOF $ gcc -Wall -g -o eseg_esempio esempio.c -lm $ ./eseg_esempio 1, 2.915, ./run_exam, (null) $ ./eseg_esempio 1234567890qwerty 2, 3.082, ./run_exam, 1234567890qwerty
In questo esempio, l'uso di "-lm
" è necessario per fare
il link alla libreria "/usr/lib/libm.so
" nel pacchetto
libc6
per sqrt
(3). La libreria reale è
in "/lib/
" con nome file "libm.so.6
",
che è un collegamento simbolico a "libm-2.7.so
".
Si guardi l'ultimo elemento nel testo di output: ci sono più di 10 caratteri
anche se è stato specificato "%10s
".
L'uso di funzioni che operano su puntatori di memoria senza controlli sui
limiti, come sprintf
(3) e strcpy
(3) è
deprecato per prevenire exploit di tipo buffer overflow che sfruttano gli
effetti di superamento dei limiti di grandezza dei dati.
Il debug è un'importante fase del processo di programmazione. Sapere come fare il debug dei programmi rende buoni utenti Debian in grado di creare segnalazioni di bug significative.
Lo strumento di debug principale in Debian è
gdb
(1) che permette di ispezionare un programma mentre
viene eseguito.
Installare gdb
e i programmi correlati nel modo seguente.
# apt-get install gdb gdb-doc build-essential devscripts
Un buon tutorial su gdb
viene fornito da "info
gdb
" o lo si può trovare altrove
in rete. Quello che segue è un piccolo esempio d'uso di
gdb
(1) su di un "programma
" compilato
con l'opzione "-g
" per produrre informazioni di debug.
$ gdb program (gdb) b 1 # imposta un punto di interruzione alla riga 1 (gdb) run argomenti # esegue programma con argomenti (gdb) next # riga successiva ... (gdb) step # passo successivo ... (gdb) p param # stampa parametro ... (gdb) p param=12 # imposta il valore a 12 ... (gdb) quit
![]() |
Suggerimento |
---|---|
Molti comandi |
Dato che tutti i binari installati in un sistema Debian dovrebbero essere,
in modo predefinito, snelliti con strip, la maggior parte dei simboli di
debug non è presente nei normali pacchetti. Per poter fare il debug di
pacchetti Debian con gdb
(1) devono essere installati i
corrispondenti pacchetti *-dbg
(ad esempio
libc6-dbg
per libc6
).
Se un pacchetto di cui si deve fare il debug non fornisce il proprio
pacchetto *-dbg
corrispondente, è necessario installarlo
dopo averlo ricompilato nel modo seguente.
$ mkdir /percorso/nuovo ; cd /percorso/nuovo $ sudo apt-get update $ sudo apt-get dist-upgrade $ sudo apt-get install fakeroot devscripts build-essential $ sudo apt-get build-dep nome_pacchetto_sorgente $ apt-get source nome_pacchetto $ cd nome_pacchetto*
Correggere i bug se necessario.
Spostare la versione del pacchetto ad una che non crei conflitti con le
versioni ufficiali di Debian, ad esempio una che termini con
"+debug1
" quando si ricompilano versioni di cui esiste un
pacchetto, o una che termini con "~pre1
" quando si
ricompilano versioni non ancora rilasciate in pacchetti nel modo seguente.
$ dch -i
Compilare ed installare i pacchetti con i simboli di debug nel modo seguente.
$ export DEB_BUILD_OPTIONS=nostrip,noopt $ debuild $ cd .. $ sudo debi nome_pacchetto*.changes
È necessario controllare gli script di compilazione del pacchetto ed
assicurarsi di usare "CFLAGS=-g -Wall
" per la
compilazione di binari.
Quando un programma va in crash, è una buona idea inviare un segnalazione di bug riportando le informazioni di backtrace.
Il backtrace può essere ottenuto eseguendo le azioni seguenti.
gdb
(1).
Riprodurre il crash.
gdb
.
bt
" al prompt di gdb
.
Nel caso in cui in programma si blocca, si può farlo andare in crash
premendo Ctrl-C
nel terminale in cui è in esecuzione
gdb
, ottenendo così il prompt di gdb
.
![]() |
Suggerimento |
---|---|
Spesso si vede un backtrace in cui una o più delle prime righe sono in
" |
$ MALLOC_CHECK_=2 gdb hello
Tabella 12.12. Elenco di comandi gdb avanzati
comando | descrizione degli scopi del comando |
---|---|
(gdb) thread apply all bt
|
ottenere un backtrace per tutti i thread di un programma multi-thread |
(gdb) bt full
|
ottenere i parametri nello stack delle chiamate di funzione |
(gdb) thread apply all bt full
|
ottenere un backtrace e parametri: combinazione delle due opzioni precedenti |
(gdb) thread apply all bt full 10
|
ottenere un backtrace e i parametri per le prime dieci chiamate nello stack per eliminare l'output irrilevante |
(gdb) set logging on
|
scrivere un registro dell'output di gdb in un file (il
file predefinito è "gdb.txt ")
|
Se un programma gnome preview1
ha ricevuto un errore X,
si dovrebbe leggere un messaggio del tipo seguente.
The program 'preview1' received an X Window System error.
Se ciò avviene, si può provare ad eseguire il programma con
"--sync
" ed interrompere alla funzione
"gdk_x_error
" per ottenere un backtrace.
Per scoprire le dipendenze di un programma da librerie, usare
ldd
(1) nel modo seguente.
$ ldd /bin/ls librt.so.1 => /lib/librt.so.1 (0x4001e000) libc.so.6 => /lib/libc.so.6 (0x40030000) libpthread.so.0 => /lib/libpthread.so.0 (0x40153000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Affinché ls
(1) funzioni in un ambiente "chroot", le
librerie in questione devono essere disponibili nell'ambiente "chroot".
Vedere Sezione 9.5.6, «Tenere traccia delle attività di un programma».
In Debian sono disponibili svariati strumenti di rilevazione di memory leak.
Tabella 12.13. Elenco di strumenti per rilevazione di memory leak
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
libc6-dev *
|
V:46, I:68 | 11292 |
mtrace (1): funzionalità di debug malloc in glibc
|
valgrind *
|
V:1.3, I:6 | 136416 | strumento di debug e profilazione per la memoria |
kmtrace *
|
V:0.3, I:2 | 324 |
tracciatore per memory leak di KDE che usa mtrace (1) di
glibc
|
alleyoop *
|
V:0.05, I:0.3 | 596 | frontend per Valgrind, programma di controllo della memoria |
electric-fence *
|
V:0.05, I:0.8 | 120 | strumento di debug malloc (3)
|
leaktracer *
|
V:0.01, I:0.11 | 116 | tracciatore di memory leak per programmi C++ |
libdmalloc5 *
|
V:0.01, I:0.2 | 356 | libreria per il debug dell'allocazione di memoria |
mpatrolc2 *
|
V:0.00, I:0.01 | 3592 | libreria per il debug dell'allocazione di memoria |
Esistono strumenti simili a lint per l'analisi statica del codice.
Tabella 12.14. Elenco di strumenti per l'analisi statica del codice
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
splint *
|
V:0.06, I:0.5 | 1836 | strumento per controllare staticamente la presenza di bug in programmi C |
rats
*
|
V:0.06, I:0.2 | 876 | Rough Auditing Tool for Security, strumento di controllo grezzo per la sicurezza (codice C, C++, PHP, Perl e Python) |
flawfinder *
|
V:0.01, I:0.15 | 192 | strumento per esaminare codice sorgente C/C++ e per cercare punti deboli per la sicurezza |
perl
*
|
V:88, I:99 | 18528 |
interprete con controllore interno statico del codice:
B::Lint (3perl)
|
pylint *
|
V:0.2, I:0.7 | 576 | strumento di controllo statico del codice Python |
jlint
*
|
V:0.01, I:0.09 | 156 | strumento di controllo per programmi Java |
weblint-perl *
|
V:0.10, I:0.7 | 28 | strumento di controllo della sintassi e dello stile di base per HTML |
linklint *
|
V:0.05, I:0.3 | 432 | controllore veloce di collegamenti e strumento per manutenzione di siti web |
libxml2-utils *
|
V:3, I:49 | 160 |
utilità con xmllint (1) per convalidare file XML
|
Flex è un veloce generatore di analizzatori lessicali compatibile con Lex.
Un tutorial per flex
(1) viene fornito da "info
flex
".
È necessario fornire i propri "main()
" e
"yywrap()
". Altrimenti il proprio programma flex dovrebbe
apparire così per compilare senza una libreria. Questo è dovuto al fatto che
"yywrap
" è una macro e "%option main
"
abilita implicitamente "%option noyywrap
".
%o Fabbrica componente Echo
In alternativa si può compilare con l'opzione per linker "
-lfl
" alla fine della propria riga di comando
cc
(1) (come "-ll
" per
AT&T-Lex). In questo caso non è necessario usare
"%option
".
Svariati pacchetti Debian forniscono un generatore di parser LR lookahead o parser LALR combatibile con Yacc.
Tabella 12.15. Elenco di generatori di parser LALR compatibili con Yacc
pacchetto | popcon | dimensione | descrizione |
---|---|---|---|
bison
*
|
V:2, I:15 | 1504 | generatore GNU di parser LALR |
byacc
*
|
V:0.09, I:1.2 | 168 | generatore Berkeley di parser LALR |
btyacc *
|
V:0.00, I:0.07 | 248 |
generatore di parser backtracking basato su byacc
|
Un tutorial per bison
(1) viene fornito da "info
bison
".
È necessario fornire i propri "main()
" e
"yyerror()
". "main()
" chiama
"yyparse()
" che a sua volta chiama
"yylex()
", solitamente creato con Flex.
%% %%
Autoconf è uno strumento per produrre script shell che configurano automaticamente pacchetti software di codice sorgente, in modo da adattarsi a molti tipi di sistemi *nix usando l'intero sistema di compilazione GNU.
autoconf
(1) produce lo script di configurazione
"configure
". "configure
" crea
automaticamente un "Makefile
" personalizzato usando il
modello "Makefile.in
".
![]() |
Avvertimento |
---|---|
Non sovrascrivere mai file di sistema quando si installano programmi compilati in proprio. |
Debian non tocca i file in "/usr/local/
" o
"/opt
". Perciò se si compila un programma dai sorgenti,
installarlo in "/usr/local/
" in modo che non interferisca
con Debian.
$ cd src $ ./configure --prefix=/usr/local $ make $ make install # questo mette i file nel sistema
Se si hanno i sorgenti originali e questi usano
autoconf
(1)/automake
(1), e se ci si
ricorda la configurazione usata, eseguire quanto segue per disinstallare un
programma.
$ ./configure "tutte-le-opzioni-che-erano-state-usate" # make uninstall
In alternativa, se si è assolutamente certi che il processo di installazione
mette i file solo in "/usr/local/
" e lì non c'è nulla di
importante, si può cancellare tutto ciò che contiene con la riga di comando
seguente.
# find /usr/local -type f -print0 | xargs -0 rm -f
Se non si è sicuri di dove siano installati i file, si dovrebbe prendere in
considerazione l'uso di checkinstall
(8) dal pacchetto
checkinstall
, che fornisce un'indicazione per una
disinstallazione pulita.
Benché qualsiasi script AWK possa essere
riscritto automaticamente in Perl usando
a2p
(1), gli script AWK di una sola riga si convertono
meglio manualmente in script Perl di una riga.
Si consideri il seguente pezzetto di script AWK.
awk '($2=="1957") { print $3 }' |
Ciò equivale ad una qualsiasi delle righe seguenti.
perl -ne '@f=split; if ($f[1] eq "1957") { print "$f[2]\n"}' |
perl -ne 'if ((@f=split)[1] eq "1957") { print "$f[2]\n"}' |
perl -ne '@f=split; print $f[2] if ( $f[1]==1957 )' |
perl -lane 'print $F[2] if $F[1] eq "1957"' |
perl -lane 'print$F[2]if$F[1]eq+1957' |
L'ultima è una sorta di indovinello; sfrutta le seguenti caratteristiche di Perl.
Per le opzioni per la riga di comando vedere
perlrun
(1). Per altri script Perl pazzi può essere
interessante guardare Perl Golf.
Pagine web dinamiche interattive di base possono essere create nel modo seguente.
La compilazione e il cliccare sulle voci nel modulo invia una delle stringhe URL seguenti con i parametri codificati dal browser al web server.
http://www.foo.dom/cgi-bin/program.pl?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
http://www.foo.dom/cgi-bin/program.py?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
http://www.foo.dom/program.php?VAR1=VAL1&VAR2=VAL2&VAR3=VAL3
"
%nn
" nell'URL viene sostituito dal carattere con valore
esadecimale nn
.
QUERY_STRING="VAR1=VAL1
VAR2=VAL2 VAR3=VAL3"
".
program.*
") sul server web è eseguito con la variabile
d'ambiente "$QUERY_STRING
".
stdout
del programma CGI viene inviato al browser web
ed è presentato come pagina web dinamica interattiva.
Per ragioni di sicurezza è bene non creare a mano nuovi metodi per analizzare i parametri CGI. Per loro esistono moduli Perl e Python comprovati. PHP è fornito con queste funzionalità. Quando è necessaria l'archiviazione dei dati client vengono usati i cookie HTTP. Quando è necessaria l'elaborazione dei dati lato client, viene spesso usato Javascript.
Per maggiori informazioni vedere CGI (Common Gateway Interface), Apache Software Foundation e JavaScript.
Cercare "CGI tutorial" su Google digitando l'URL codificato http://www.google.com/search?hl=en&ie=UTF-8&q=CGI+tutorial direttamente nell'indirizzo del browser è un buon modo per vedere lo script CGI in azione sul server di Google.
Esistono programmi per convertire codice sorgente.
Tabella 12.16. Elenco di strumenti per la traduzione di codice sorgente
pacchetto | popcon | dimensione | parola chiave | descrizione |
---|---|---|---|---|
perl
*
|
V:88, I:99 | 18528 | AWK→PERL |
converte codice sorgente da AWK a PERL:a2p (1)
|
f2c
*
|
V:0.12, I:1.2 | 448 | FORTRAN→C |
converte codice sorgente da FORTRAN 77 a C/C++: f2c (1)
|
protoize *
|
V:0.00, I:0.09 | 100 | ANSI C | crea/rimuove prototipi ANSI da codice C |
intel2gas *
|
V:0.01, I:0.07 | 344 | intel→gas | convertitore da NASM (formato Intel) a GAS (GNU Assembler) |
Se si desidera creare un pacchetto Debian, leggere i documenti seguenti.
debuild
(1), pbuilder
(1) e
pdebuild
(1)
maint-guide
)
developers-reference
)
debian-policy
)
Ci sono pacchetti come dh-make
,
dh-make-perl
, ecc., che aiutano nella creazione dei
pacchetti.