Appendice F
Utilizzare il debugger di Visual Studio
Obiettivi
Essere in grado di impostare i breakpoint e di eseguire un programma nel debugger.
Essere in grado di utilizzare il comando Continue per continuare l'esecuzione.
■
Essere in grado di utilizzare la finestra Locals per visualizzare e modificare i valori delle variabili.
■
Essere in grado di utilizzare la finestra Watch per valutare le espressioni.
■
Essere in grado di utilizzare i comandi Step Into, Step Out e Step Over per controllare l'esecuzione.
■
Essere in grado di utilizzare la finestra Autos per visualizzare le variabili che vengono utilizzate nei
comandi prossimi a quello corrente.
■
■
F.1 Introduzione
Nel Capitolo 2 avete imparato che esistono due tipi di errori, ovvero, errori di compilazione ed errori logici ed
avete imparato come eliminare i primi dal vostro codice. Gli errori logici (denominati anche bug) non
impediscono che un programma venga compilato con successo, ma possono far sì che il programma stesso
produca dei risultati erronei al momento dell'esecuzione. Molti produttori di compilatori C forniscono anche un
software noto come debugger, che vi permette di controllare l'esecuzione dei vostri programmi per individuare ed
eliminare gli errori logici. Il debugger si rivelerà come uno dei più importanti strumenti per lo sviluppo di
programmi. Questa appendice illustra le caratteristiche chiave del debugger del Visual Studio. L'Appendice H
illustra le caratteristiche e le possibilità offerte dal debugger GNU.
F.2 I breakpoint ed il comando Continue
Iniziamo il nostro studio del debugger investigando i breakpoint, che sono dei marcatori che possono essere
impostati in corrispondenza di ogni riga eseguibile del codice. Quando l'esecuzione del programma raggiunge un
breakpoint, viene effettuata una pausa, consentendovi di esaminare i valori delle variabili per aiutarvi a
determinare se ci sia un errore logico. Per esempio, potete esaminare il valore di una variabile che memorizza il
risultato di un calcolo per determinare se quest'ultimo sia stato eseguito correttamente. Si noti che tentare di
inserire un breakpoint in corrispondenza di una linea di codice che non sia eseguibile (come un commento)
imposterà il breakpoint alla prossima linea eseguibile di codice nella relativa funzione.
Per illustrare le caratteristiche del debugger, utilizziamo il programma in Figura F.1, che trova il massimo di tre
interi. L'esecuzione inizia in corrispondenza del main (righe 8–22). I tre interi vengono inseriti con la scanf (riga 15).
In seguito, gli interi sono passati a maximum (riga 19), che ne determina il massimo. Quest'ultimo è il valore
restituito al main dal comando return in maximum (riga 38). Il valore restituito viene poi visualizzato per mezzo del
comando printf (riga 19).
1 /* Fig. F.1: figG_01.c
2
Trovare il massimo di tre interi */
3 #include <stdio.h>
4
5 int maximum( int x, int y, int z ); /* prototipo di funzione */
6
7 /* l’esecuzione del programma inizia dalla funzione main */
8 int main( void )
9{
10
int number1; /* primo intero */
11
int number2; /* secondo intero */
12
int number3; /* terzo intero */
13
printf( "Enter three integers: " );
14
Copyright (C) 2010 Apogeo
15
scanf( "%d%d%d", &number1, &number2, &number3 );
16
17
/* number1, number2 e number3 sono gli argomenti
18
della chiamata di funzione a maximum */
19
printf( "Maximum is: %d\n", maximum( number1, number2, number3 ) );
20
21
return 0; /* indica che il programma è terminato con successo */
22 } /* fine della funzione main */
23
24 /* Definizione della funzione maximum */
25 /* x, y e z sono i parametri */
26 int maximum( int x, int y, int z )
27 {
28
int max = x; /* si assuma che x sia il massimo */
29
if ( y > max ) { /* se y è maggiore di max, assegna y a max */
30
31
max = y;
32
} /* end if */
33
if ( z > max ) { /* se z è maggiore di max, assegna z a max */
34
35
max = z;
36
} /* end if */
37
return max; /* max è il valore massimo */
38
39 } /* fine della funzione maximum */
Fig. F.1 | Determinare il massimo di tre interi.
Creare un progetto in Visual C++ 2008 Express
Nei passi seguenti creerete un progetto che includa il codice della Figura F.1.
1. Selezionate File > New > Project... in Visual C++ 2008 Express per visualizzare la finestra di dialogo New Project.
2. Nell'elenco Project types:, selezionate Win32 e nell'elenco Templates, selezionate Win32Console Application.
3. Inserite un nome per il vostro progetto nel campo Name: e specificate dove volete salvarlo nel vostro computer
nel campo Location:, poi fate clic su OK.
4. Nella finestra di dialogo Win32 Application Wizard fate clic su Next >.
5. In Applicationtype: selezionate Console application e in Additional options: selezionate Empty project, poi fate clic su Finish.
6. Nella finestra Solution Explorer fate clic con il tasto destro sulla cartella Source Files del vostro progetto e
selezionate Add > Existing Item... per visualizzare la finestra di dialogo Add Existing Item.
7. Individuate la cartella contenente il codice degli esempi dell'Appendice H, selezionate il file con il codice e fate
clic su Add.
Abilitare la modalità di debug (Debug Mode) e inserire i breakpoint
Nei passi seguenti utilizzerete i breakpoint e diversi comandi del debugger per esaminare il valore della variabile
number1 dichiarata in Figura F.1.
1. Abilitare il debugger. Il debugger normalmente è abilitato per default. Nel caso in cui non lo sia, dovrete
cambiare le impostazioni del menu a tendina Solution Configurations (Figura F.2) situato nella barra degli
strumenti. Per far ciò, fate clic sulla freccia verso il basso del menu a tendina e poi selezionate Debug.
Fig. F.2 | Abilitare il debugger.
Copyright (C) 2010 Apogeo
2. Inserire i breakpoint. Aprite il file figG_01.c facendo doppio clic su di esso nel Solution Explorer. Per inserire un
breakpoint, fate clic dentro la barra grigia alla sinistra della finestra del codice (margin indicator bar in Figura F.3)
in prossimità della riga in cui volete effettuare l'interruzione oppure fate clic con il tasto destro su quella linea di
codice e selezionate Break- point > Insert Breakpoint. Potete impostare tanti breakpoint quanti ne saranno necessari.
Impostate i breakpoint in corrispondenza delle righe 14 e 19 del vostro codice. Un circoletto rosso apparirà sul
barra che indica il margine nel punto in cui avete fatto clic, in modo da indicare che un breakpoint è stato
impostato (Figura F.3). Quando il programma viene eseguito, il debugger effettua una pausa nell'esecuzione in
corrispondenza di ogni linea che contiene un breakpoint. Si dice che il programma si trova in break mode quando
il debugger lo mette in pausa. I breakpoint possono essere impostati prima di far girare un programma, mentre si
trova in break mode e mentre è in corso di esecuzione.
Fig. F.3 | Impostare due breakpoint.
3. Iniziare il debug. Dopo aver impostato i breakpoint nell'editor del codice, selezionate Build>Build Solution per
compilare il programma, poi selezionate Debug > Start Debugging per iniziare il processo di debugging. [Nota: Se non
compilate prima il programma, esso sarà comunque compilato nel momento in cui selezionerete Debug > Start
Debugging.] Quando eseguite il debug di un'applicazione console, appare una finestra Command Prompt (Figura F.4)
in cui potete specificare gli input del programma e vederne l'output. Il debugger entra in break mode nel momento
in cui l'esecuzione raggiunge il breakpoint in riga 14.
Fig. F.4 | Il programma Maximum Numbers in esecuzione.
4. Esaminare l'esecuzione del programma. In seguito all'ingresso in break mode in corrispondenza del primo
breakpoint (riga 14), l'IDE diventa la finestra attiva (Figura F.5). La freccia gialla alla sinistra della riga 14 indica
che tale linea contiene il prossimo comando da eseguire.
Fig. F.5 | Esecuzione del programma sospesa in corrispondenza del primo breakpoint.
Copyright (C) 2010 Apogeo
5. Utilizzare il comando Continue per riprendere l'esecuzione. Per riprendere l'esecuzione, selezionate Debug >
Il comando Continue riprende l'esecuzione del programma fino al prossimo breakpoint o fino al
raggiungimento della fine del main, a seconda di quale evento si verifichi per primo. Il programma continua ad
eseguire ed effettua una pausa in corrispondenza della riga 15. Inserite i valori 22, 85, e 17 per i tre interi. Il
programma esegue finché non si ferma al prossimo breakpoint (riga 19). Notate che, quando posizionate il vostro
puntatore del mouse sul nome della variabile number1, il valore in essa contenuto viene visualizzato in un Quick
Info box (Figura F.6). Come potete constatare, ciò può aiutarvi ad individuare degli errori logici nei vostri
programmi.
Continue.
Fig. F.6 | Quick Info box che visualizza il valore di una variabile.
6. Impostare un breakpoint in corrispondenza della parentesi di chiusura del main. Impostate un breakpoint in riga
22 del codice sorgente facendo clic sulla barra indicante il margine alla sinistra della riga 22. Questo fatto
impedirà al programma di chiudersi immediatamente dopo aver visualizzato il suo risultato. Quando
non ci sono più breakpoint in corrispondenza dei quali sospendere l'esecuzione, il programma eseguirà fino al
completamento e la finestra del Command Prompt verrà chiusa. Se non impostate questo breakpoint, non sarete in
grado di vedere l'output del programma prima che la finestra della console venga chiusa.
7. Continuare l'esecuzione del programma. Utilizzate il comando Debug > Continue per eseguire il codice fino al
prossimo breakpoint. Il programma visualizza il risultato del suo calcolo (Figura F.7).
Fig. F.7 | Output del programma.
8. Eliminare un breakpoint. Fate clic sul breakpoint nella barra indicante il margine.
9. Completare l'esecuzione del programma. Selezionate Debug > Continue per eseguire il programma fino al suo
completamento.
In questa sezione, avete imparato ad attivare il debugger e ad impostare i breakpoint in modo da esaminare i
risultati del codice mentre il programma è in esecuzione. Avete anche imparato come continuare l'esecuzione in
seguito alla sospensione di quest'ultima in corrispondenza di un breakpoint e come rimuovere i breakpoint.
F.3 Le finestre Locals e Watch
Nella sezione precedente avete imparato che la caratteristica Quick Info vi permette di esaminare il valore di una
variabile. In questa sezione imparerete ad usare la finestra Locals per assegnare nuovi valori alle variabili mentre il
vostro programma è in esecuzione. Userete la finestra Watch anche per esaminare il valore di espressioni più
complesse.
Copyright (C) 2010 Apogeo
1. Inserire i breakpoint. Cancellate i breakpoint esistenti selezionando Debug > Delete All Breakpoints. Poi impostate
un breakpoint in corrispondenza della riga 19 del codice sorgente facendo clic nella barra che indica il margine
alla sinistra della riga 19 (Figura F.8).
Fig. F.8 | Impostare i breakpoint in corrispondenza delle righe 25 e 28.
2. Iniziare il debugging. Selezionate Debug > Start. Inserite i valori 22, 85, e 17 in corrispondenza del prompt Enter
three integers: e premete Enter in modo che il vostro programma legga i valori che avete appena inserito.
3. Sospendere l'esecuzione del programma. Il debugger entra in break mode in corrispondenza della riga 19
(Figura F.9). A questo punto la riga 15 ha letto i valori che avete inserito per number1 (22), number2 (85) e number3
(17). La riga 19 rappresenta il prossimo comando da eseguire.
Fig. F.9 | L'esecuzione del programma è sospesa quando il debugger raggiunge il breakpoint della riga 19.
4. Esaminare i dati. In break mode potete esaminare il valore delle vostre variabili locali utilizzando la finestra
Locals del debugger, normalmente visibile nella parte inferiore sinistra dell'IDE quando siete in modalità di
debugging. Se non è visibile al momento, potete esaminare la finestra Locals, selezionando Debug > Windows > Locals.
La Figura F.10 mostra i valori delle variabili locali del main, ovvero, number1 (22), number2 (85) e number3 (17).
Fig. F.10 | Esaminare le variabili number1, number2 e number3.
5. Valutare le espressioni aritmetiche e booleane. Potete valutare le espressioni aritmetiche e booleane utilizzando
la finestra Watch. Potete tenere visibili fino a quattro finestre Watch. Selezionate Debug > Windows > Watch > Watch 1.
Nella prima riga della colonna Name digitate (number1 + 3) * 5, poi premete Enter. Il valore di questa espressione (125
Copyright (C) 2010 Apogeo
in questo caso) viene mostrato nella colonna Value (Figura F.11). Nella riga successiva della colonna Name digitate
number== 3, poi premete Enter. Questa espressione determina se il valore di number1 sia 3. Le espressioni contenenti
l'operatore == (o ogni altro operatore relazionale o di uguaglianza) vengono considerate delle espressioni di tipo
bool. Il valore dell'espressione in questo caso è false (Figura F.11), in quanto number1 al momento contiene 22, non 3.
Fig. F.11 | Esaminare i valori delle espressioni.
6. Modificare i valori. In base ai valori inseriti dall'utente (22, 85 e 17), il numero massimo mandato in output dal
programma dovrebbe essere 85. Tuttavia, potete utilizzare la finestra Locals per cambiare i valori delle variabili
durante l'esecuzione del programma. Ciò può rivelarsi utile per sperimentare diversi valori e per individuare gli
errori logici. Nella finestra Locals, fate clic sul campo Value nella riga corrispondente a number1 per selezionare il
valore 22. Digitate 90, poi premete Enter. Il debugger cambierà il valore di number1 e visualizzerà il suo nuovo
valore in rosso (Figura F.12).
Fig. F.12 | Modificare il valore di una variabile.
7. Impostare un breakpoint in corrispondenza della parentesi di chiusura del main. Impostate un breakpoint in riga
22 del codice sorgente per impedire al programma di chiudersi immediatamente dopo aver visualizzato il suo
risultato. Se non impostate questo breakpoint, non sarete in grado di vedere l'output del programma prima che la
finestra della console si chiuda.
8. Riprendere l'esecuzione e vedere il risultato del programma. Selezionate Debug > Continue per continuare
l'esecuzione del programma. La funzione main eseguirà fino al comando return statement in riga 21 e visualizzerà il
risultato. Notate che il risultato sarà 90 (Figura F.13). Questo dimostra che il Passo 7 ha modificato il valore di
number1 a 90 dal valore originale (85).
Fig. F.13 | L'output visualizzato dopo la modifica del valore della variabile number1.
9. Interrompere la sessione di debugging. Selezionate
Prompt. Rimuovete tutti i breakpoint rimanenti.
Debug > Stop Debugging.
Ciò chiuderà la finestra
Command
In questa sezione avete imparato ad utilizzare le finestre Watch e Locals per valutare le espressioni aritmetiche e
booleane. Avete anche imparato come modificare il valore di una variabile durante l'esecuzione del programma.
F.4 Controllare l'esecuzione utilizzando i comandi Step Into, Step
Over, Step Out e Continue
A volte eseguire un programma riga per riga vi può aiutare a verificare che il codice di una funzione venga
eseguito correttamente ed a individuare e correggere gli errori logici. I comandi che imparerete in questa sezione
vi permetteranno di eseguire una funzione riga per riga, di eseguire tutte le istruzioni di una funzione in un colpo
solo o di eseguire solamente le istruzioni rimanenti di una funzione (nel caso in cui abbiate già eseguito alcune
istruzioni dentro la funzione).
Copyright (C) 2010 Apogeo
1. Impostare un breakpoint. Impostate un breakpoint in corrispondenza della riga 19 facendo clic sulla barra che
indica il margine alla sinistra della riga.
2. Far partire il debugger. Selezionate Debug > Start. Inserite i valori 22, 85 e 17 al prompt Enter three integers:.
L'esecuzione si fermerà quando il programma raggiungerà il breakpoint in corrispondenza della riga 19.
3. Utilizzare il comando Step Into. Il comando Step Into esegue la prossima istruzione nel programma (riga 19), poi
si arresta immediatamente. Se quell'istruzione contiene una chiamata di funzione (come avviene in questo caso), il
controllo viene trasferito all'interno della funzione chiamata. Ciò vi permette di eseguire singolarmente ogni
comando all'interno della funzione per confermare l'esecuzione della funzione. Selezionate Debug > Step Into per
entrare nella funzione maximum. In seguito selezionate nuovamente Debug > Step Into in modo che la freccia gialla si
posizioni in corrispondenza della riga 28 come mostrato in Figura F.14.
4. Utilizzare il comando Step Over. Selezionate Debug > Step Over per eseguire il comando corrente (riga 28 in Figura
F.14) e trasferire il controllo alla riga 30 (Figura F.15). Il comando Step Over si comporta come il comando Step Into
quando la prossima istruzione da eseguire non contiene una chiamata di funzione. Vedrete come il comando Step
Over differisca dal comando Step Into nel Passo 10.
Fig. F.14 | Eseguire passo per passo la funzione maximum.
Fig. F.15 | Eseguire il comando corrente nella funzione maximum.
5. Utilizzare il comando Step Out. Selezionate Debug > Step Out per eseguire le istruzioni rimanenti nella funzione e
restituire il controllo alla prossima istruzione eseguibile (riga 21 in Figura F.1). Spesso, nelle funzioni più lunghe,
vorrete controllare alcune linee chiave di codice per poi continuare nel debugging del codice del chiamante. Il
comando Step Out vi permette di continuare l'esecuzione del programma nel chiamante senza dover eseguire riga
per riga l'intera funzione chiamata.
6. Impostare un breakpoint. Impostate un breakpoint alla fine del main in corrispondenza della riga 22 della Figura
F.1. Farete uso di questo breakpoint nel passo successivo.
7. Utilizzare il comando Continue. Selezionate Debug > Continue per continuare l'esecuzione fino al raggiungimento
del prossimo breakpoint in corrispondenza della riga 22. Usare il comando Continue si rivela utile quando volete
eseguire tutto il codice fino al prossimo breakpoint.
Copyright (C) 2010 Apogeo
8. Arrestare il debugger. Selezionate Debug > Stop Debugging per terminare la sessione di debugging. Ciò provocherà
la chiusura della finestra del Command Prompt.
9. Far partire il debugger. Prima di poter illustrare la prossima caratteristica del debugger, fate partire nuovamente
il debugger. Avviatelo, come avete fatto nel Passo 2, ed inserite 22, 85 e 17 in risposta al prompt. Il debugger entrerà
in break mode in corrispondenza della riga 19.
10. Utilizzare il comando Step Over. Selezionate Debug > Step Over (Figura F.16). Ricordatevi che questo comando si
comporta come il comando Step Into quando la prossima istruzione da eseguire non contiene una chiamata di
funzione. Nel caso in cui la prossima istruzione da eseguire contenga una chiamata di funzione, la funzione
chiamata verrà eseguita nella sua interezza (senza effettuare pause nell'esecuzione di nessuna istruzione all'interno
della funzione) e la freccia gialla avanzerà alla prossima linea eseguibile (dopo la chiamata di funzione) nella
funzione corrente. In questo caso il debugger eseguirà la riga 19, situata nel main (Figura F.1). La riga 19
richiamerà la funzione maximum. In seguito il debugger effettuerà una pausa in corrispondenza della riga 21,
ovvero, la prossima linea eseguibile nella funzione corrente, main.
Fig. F.16 | Utilizzare il comando Step Over.
11. Arrestare il debugger. Selezionate
tutti i breakpoint rimanenti.
Debug > Stop Debugging.
Ciò chiuderà la finestra
Command Prompt.
Rimuovete
In questa sezione avete imparato come usare il comando Step Into del debugger per correggere le funzioni
richiamate durante l'esecuzione del vostro programma. Avete visto come il comando Step Over possa essere
utilizzato per oltrepassare una chiamata di funzione. Avete utilizzato il comando Step Out per continuare
l'esecuzione fino alla fine della funzione corrente. Avete imparato anche che il comando Continue continua
l'esecuzione fino al raggiungimento di un altro breakpoint o all'uscita dal programma.
F.5 La finestra Autos
La finestra Autos visualizza le variabili utilizzate nell'istruzione precedentemente eseguita (includendo il valore di
ritorno di una funzione, se è il caso) e le variabili nella prossima istruzione da eseguire.
1. Impostare i breakpoint. Impostate i breakpoint in corrispondenza delle righe 14 e 19 nel main facendo clic sulla
barra che indica il margine.
2. Utilizzare la finestra Autos. Avviate il debugger selezionando Debug>Start. Quando il debugger entra in break
mode in corrispondenza della riga 14, aprite la finestra Autos (Figura F.17) selezionando Debug > Windows > Autos.
Dato che abbiamo appena iniziato l'esecuzione del programma, la finestra Autos elencherà soltanto le variabili
coinvolte nel prossimo comando da eseguire, ovvero in questo caso, number1, number2 e number3. Visualizzare il
valore memorizzato in una variabile vi permette di verificare che il vostro programma stia manipolando le
variabili correttamente. Notate che number1, number2 e number3 contengono valori negativi molto grandi. Tali valori,
che possono differire ogni volta che il programma viene eseguito, sono i valori non inizializzati delle variabili.
Questi valori imprevedibili (e spesso indesiderabili) sono la dimostrazione dell'importanza di inizializzare tutte le
variabili in C prima del loro utilizzo.
Copyright (C) 2010 Apogeo
Fig. F.17 | La finestra Autos mentre visualizza i valori di number1, number2 e number3.
3. Continuare l'esecuzione. Selezionate Debug > Continue per eseguire il programma fino al raggiungimento del
secondo breakpoint in corrispondenza della riga 19. Al prompt di input del programma, inserite i valori dei tre
interi. La finestra Autos aggiornerà i valori di number1, number2 e number3 dopo la loro inizializzazione. I loro valori
appariranno in rosso per indicare che sono stati appena modificati. (Figura F.18)
Fig. F.18 | La finestra Autos mentre visualizza le variabili locali number1, number2 e number3.
4. Inserire dei dati. Selezionate Debug > Step
ritorno della funzione maximum (Figura F.19).
Over
per eseguire la riga 19. La finestra
Autos
visualizza il valore di
Fig. F.19 | La finestra Autos mentre visualizza il valore di ritorno della funzione maximum.
5. Arrestare il debugger. Selezionate Debug > Stop Debugging per terminare la sessione di debugging. Rimuovete tutti
i breakpoint rimanenti.
F.6 Conclusione
In questa appendice avete imparato come inserire, disabilitare ed eliminare i breakpoint nel debugger di Visual
Studio. I breakpoint vi permettono di effettuare delle pause nell'esecuzione del programma in modo da esaminare i
valori delle variabili. Questa caratteristica vi aiuterà ad individuare e correggere gli errori logici nei vostri
programmi. Avete visto come utilizzare le finestre Locals e Watch per esaminare il valore di un'espressione e per
cambiare il valore di una variabile. Avete anche imparato i comandi Step Into, Step Over, Step Out e Continue che
possono essere utilizzati per determinare se una funzione venga eseguita correttamente. Infine avete imparato
come usare la finestra Autos per esaminare le variabili usate in particolare nel comando precedente ed in quello
successivo.
Esercizi di autovalutazione
F.1
Completate gli spazi in ognuna delle seguenti frasi:
a) Quando il debugger sospende l'esecuzione del programma in corrispondenza di un breakpoint, si dice che il programma
sia in __________.
b) La caratteristica __________ di Visual Studio 2008 vi permette di esaminare il valore di una variabile posizionando il
mouse sul nome della variabile nel codice.
c) Potete esaminare il valore di un'espressione usando la finestra __________ del debugger.
Copyright (C) 2010 Apogeo
d) Il comando __________ si comporta come il comando Step Into quando la prossima istruzione da eseguire non contiene
una chiamata di funzione.
F.2
Stabilite quali delle seguenti affermazioni sono vere e quali false. Nel caso siano false, spiegatene il motivo.
a) Quando l'esecuzione del programma viene sospesa in corrispondenza di un breakpoint, la prossima istruzione da eseguire
è quella dopo il breakpoint.
b) Quando il valore di una variabile viene modificato, diventa giallo nelle finestre Autos e Locals.
c) Durante il debugging il comando Step Out esegue le istruzioni rimanenti nella funzione corrente e restituisce il controllo
del programma al punto in cui la funzione era stata richiamata.
Risposte agli esercizi di autovalutazione
F.1
a) break mode. b) Quick Info box. c) Watch. d) Step Over.
F.2
a) Falso. Quando l'esecuzione del programma viene sospesa in corrispondenza di un breakpoint, il prossimo comando da
eseguire è il comando corrispondente al breakpoint. b) Falso. Una variabile diventa rossa se il suo valore è stato modificato. c) Vero.
Copyright (C) 2010 Apogeo
Scarica

Appendice F - Utilizzare il debugger di Visual Studio