Esercitazione: Eseguire il debug di codice C++ con Visual Studio
Questo articolo presenta le funzionalità del debugger di Visual Studio in una procedura dettagliata. Quando si esegue il debug di un'applicazione, in genere si esegue l'app con il debugger collegato. Il debugger offre molti modi per esaminare le operazioni eseguite dal codice durante l'esecuzione del programma. È possibile passare in rassegna il codice e osservare i valori archiviati nelle variabili, nonché monitorare le variabili per vedere quando i valori cambiano. Il debugger consente di esaminare il percorso di esecuzione del codice e verificare che sia in esecuzione un ramo di codice.
In questa esercitazione:
- Avviare il debugger e sospendere in corrispondenza dei punti di interruzione
- Impara i comandi per scorrere il codice nel debugger
- Esaminare le variabili nelle finestre dei suggerimenti per i dati e del debugger
- Esaminare lo stack di chiamate
Se non si ha familiarità con il debug, è possibile leggere Debug per principianti assoluti prima di iniziare questa esercitazione. Se si desidera una visualizzazione di livello superiore delle funzionalità del debugger, vedere Esaminare prima il debugger.
Prerequisiti
Visual Studio 2022 versione 17.12 o successiva con il workload Sviluppo desktop con C++ installato.
- Per installare Visual Studio 2022 gratuitamente, passare alla pagina download di Visual Studio.
- Per installare gratuitamente Visual Studio, passare alla pagina versione e cronologia di compilazione per ulteriori informazioni.
Se Visual Studio è già disponibile, è possibile installare il carico di lavoro dall'ambiente di sviluppo interattivo :If you already have Visual Studio, you can install the workload from the Interactive Development Environment (IDE):
Selezionare strumenti >Ottenere strumenti e funzionalità.
Nel programma di installazione di Visual Studio, selezionare la scheda Workloads.
Selezionare il carico di lavoro sviluppo desktop con C++ e quindi selezionare Modifica.
Seguire le istruzioni e completare l'installazione.
Questa esercitazione usa un'applicazione demo C++ e gli screenshot presentano la sintassi C++. La maggior parte delle funzionalità illustrate è applicabile anche a C#, Visual Basic, F#, Python, JavaScript e altri linguaggi supportati da Visual Studio. Esistono alcune limitazioni da tenere presenti:
F#: la funzionalità di modifica e continuazione non è supportata.
F# e JavaScript: la finestra Autos non è supportata.
Creare un progetto
Seguire questa procedura per creare un progetto di applicazione console C++ in Visual Studio. Il tipo di progetto fornisce tutti i file modello necessari per iniziare rapidamente:
Nella finestra Start di Visual Studio
( File Start Window ) selezionareCrea un nuovo progetto :Impostare il filtro del linguaggio di
su C++ e impostare il filtro piattaforma su Windows .Nella casella Cerca immettere consolee selezionare il modello App Console dall'elenco dei risultati:
Nota
Se non viene visualizzato il modello App Console, è possibile installarlo dalla finestra Crea un nuovo progetto. Individuare la sezione Non trovi quello che stai cercando? che segue i risultati della ricerca e selezionare Installa altri strumenti e funzionalità. Nel programma di installazione di Visual Studio selezionare il carico di lavoro Sviluppo di applicazioni desktop con C++ e aggiornare l'installazione. Per ulteriori informazioni, vedere la sezione prerequisiti.
Selezionare Avanti per continuare con la pagina di configurazione.
Immettere get-started-debugging come nome project e nome soluzione per la nuova app. Scegliere la posizione predefinita Posizione o navigare verso un percorso diverso nel proprio ambiente.
Selezionare Crea per creare il nuovo progetto Node.js.
Visual Studio crea il nuovo progetto e apre la gerarchia del progetto in Esplora soluzioni . Il file get-started-debugging.cpp è aperto nell'editor di codice.
Creare l'applicazione
Creare una nuova applicazione per il progetto modificando il file get-started-debugging.cpp nell'editor di codice.
Sostituire il contenuto predefinito fornito dal modello con il codice seguente:
#include <string>
#include <vector>
#include <iostream>
void SendMessage(const std::wstring& name, int msg)
{
std::wcout << L"Hello, " << name << L"! Count to " << msg << std::endl;
}
int main()
{
std::vector<wchar_t> letters = { L'f', L'r', L'e', L'd', L' ', L's', L'm', L'i', L't', L'h' };
std::wstring name = L"";
std::vector<int> a(10);
std::wstring key = L"";
for (int i = 0; i < letters.size(); i++)
{
name += letters[i];
a[i] = i + 1;
SendMessage(name, a[i]);
}
std::wcin >> key;
return 0;
}
Avviare il debugger
A questo punto è possibile avviare il debug del codice aggiornato:
Iniziare il debug selezionando F5 o Debug > Avvia il debug. È anche possibile selezionare Avvia debug (icona a forma di freccia verde continua) sulla barra degli strumenti Debug.
Il tasto di scelta rapida F5 avvia l'applicazione con il debugger collegato al processo dell'app, ma non c'è ancora nulla di speciale da esaminare nel codice. L'app viene semplicemente caricata e viene visualizzato l'output della console:
Hello, f! Count to 1 Hello, fr! Count to 2 Hello, fre! Count to 3 Hello, fred! Count to 4 Hello, fred ! Count to 5 Hello, fred s! Count to 6 Hello, fred sm! Count to 7 Hello, fred smi! Count to 8 Hello, fred smit! Count to 9 Hello, fred smith! Count to 10
Più avanti nell'esercitazione esaminate più attentamente questa app con il debugger e esaminate altre funzionalità di debug.
Arrestare il debugger selezionando Ferma (icona rossa quadrata) sulla barra degli strumenti di debug. È anche possibile usare i tasti di scelta rapida MAIUSC + F5.
Nella finestra della console per l'applicazione in esecuzione selezionare qualsiasi chiave e quindi selezionare Immettere per chiudere la finestra.
Impostare un punto di interruzione e avviare il debugger
Prova a impostare un punto di interruzione e pausa al punto selezionato nel debugger:
Tornare al file get-started-debugging.cpp nell'editor di codice e individuare il ciclo
for
della funzionemain
:for (int i = 0; i < letters.size(); i++) { name += letters[i]; a[i] = i + 1; SendMessage(name, a[i]); }
Impostare un punto di interruzione nella riga contenente l'istruzione di codice
name += letters[i];
selezionandola nel margine sinistro della riga contenente l'istruzione. Visual Studio aggiunge un cerchio rosso nella barra per indicare il punto di interruzione impostato.Consiglio
È anche possibile posizionare il cursore su una riga di codice e selezionare F9 per attivare o disattivare il punto di interruzione per tale riga.
I punti di interruzione sono una delle funzionalità di base e essenziali del debug affidabile. Un punto di interruzione indica dove si vuole che Visual Studio sospende il codice in esecuzione. Quando l'esecuzione viene sospesa, è possibile esaminare i valori delle variabili, esaminare il comportamento della memoria o verificare se viene eseguito un ramo di codice.
Avvia l'app nel debugger selezionando F5 o Avvia debug.
Visual Studio avvia l'esecuzione dell'app. Quando il debugger raggiunge il punto di interruzione impostato, il processo di debug viene sospeso.
Visual Studio aggiunge una freccia gialla al cerchio rosso del punto di interruzione nel margine per rappresentare l'istruzione di codice dove viene sospeso il debugger. L'esecuzione del programma è sospesa e l'istruzione indicata è in attesa di essere elaborata.
Nota
L'azione F5
è relativa allo stato di esecuzione corrente dell'applicazione. Se l'app non è in esecuzione e si seleziona F5, il debugger avvia l'app e continua l'esecuzione finché non raggiunge il primo punto di interruzione impostato. Questo comportamento corrisponde al comando Debug>Avvia debug. Se l'app è già in esecuzione e si seleziona F5, l'esecuzione dell'app continua fino a quando il debugger non raggiunge il punto di interruzione o la fine del programma successivo. Questo comportamento viene mappato al comando Debug>Continua.
I punti di interruzione sono una funzionalità utile quando si conosce la riga di codice o la sezione del codice da esaminare in dettaglio. Per informazioni sui diversi tipi di punti di interruzione che è possibile impostare, ad esempio i punti di interruzione condizionali, vedere Usare il tipo corretto di punto di interruzione.
Analizzare il codice passo passo nel debugger
Un modo pratico per esplorare il codice nel debugger è usare i comandi di passo . Questi comandi consentono di eseguire l'istruzione, saltare l'istruzione, e uscire dalla sezione di codice, e anche eseguire all'indietro nell'esecuzione dell’app.
La procedura seguente evidenzia come utilizzare i tasti di scelta rapida con i comandi passo-passo per navigare rapidamente nel codice. Le azioni di menu equivalenti sono visualizzate tra parentesi.
Avvia l'app nel debugger selezionando F5 o Avvia il debugging.
Mentre il debugger è sospeso nel ciclo
for
nella funzionemain
, selezionare F11 (Debug > Passo Dentro) due volte per passare alla chiamata al metodoSendMessage
.Dopo aver selezionato F11 due volte, l'esecuzione continua con l'istruzione di codice
SendMessage(name, a[i]);
.Selezionare di nuovo F11 per entrare nel metodo
SendMessage
.Si noti che il puntatore giallo avanza nel metodo
SendMessage
:Il tasto di scelta rapida F11 avvia il comando Esegui istruzione, che fa avanzare l'esecuzione di un'istruzione dell'app alla volta. È un buon modo per esaminare il flusso di esecuzione nel modo più dettagliato. Per impostazione predefinita, il debugger ignora il codice non utente. Per altre informazioni, vedere Just My Code. Più avanti nell'esercitazione si apprenderà come spostarsi più velocemente nel codice.
Dopo aver esaminato il metodo
SendMessage
, puoi continuare il debug con il comando Esci dalla funzione. Selezionare Maiusc + F11 (Debug > Uscire).Questo comando riprende l'esecuzione dell'app (e avanza il debugger) fino a quando non viene restituito il metodo o la funzione corrente.
Al termine del comando, il debugger si interrompe nel ciclo
for
del metodomain
all'invocazione del metodoSendMessage
.Selezionare F11 più volte fino a ritornare alla chiamata del metodo
SendMessage
.Mentre il debugger è in pausa durante la chiamata al metodo, seleziona F10 (Debug > Passa Sopra).
Nota questa volta che il debugger non entra nel metodo
SendMessage
. Il collegamento F10 fa avanzare il debugger senza entrare in funzioni o metodi nel codice dell'app (il codice viene comunque eseguito). Quando si seleziona F10 nella chiamata al metodoSendMessage
(anziché F11 ), è il codice di implementazione perSendMessage
. Questo approccio è utile per ignorare il codice che non devi attualmente esaminare. Per altre informazioni sui diversi modi per spostarsi nel codice, vedere Esplorare il codice nel debugger.
Esplorare il codice con Esegui per fare clic
Un altro modo per analizzare il codice nel debugger consiste nell'usare la funzionalità Esegui fino al clic. Questa azione è simile all'impostazione di un punto di interruzione temporaneo.
Continuare con la sessione di debug:
Selezionare F5 per passare al punto di interruzione nel codice.
Nell'editor di codice scorrere fino alla definizione del metodo
SendMessage
e passare il puntatore del mouse sulla funzionestd::wcout
.Sposta il puntatore del mouse finché l'icona a forma di freccia verde Esegui per cliccare su appare a sinistra dell'istruzione del codice. Se si passa il puntatore del mouse sull'icona, viene visualizzata la descrizione comando "Esegui fino a questo punto".
Selezionare Esegui fino a fare clic su .
Il debugger avanza l'esecuzione alla posizione indicata. In questo esempio il debugger raggiunge la chiamata alla funzione
std::wcout
.
L'azione Esegui per fare clic su è utile per spostarsi rapidamente all'interno di un'area visibile del codice dell'app. È possibile usare la funzionalità in qualsiasi file aperto nell'editor di codice.
Riavviare rapidamente l'app
Riavvia rapidamente l'app selezionando Riavvia (icona a forma di freccia circolare) nella barra degli strumenti di debug. È anche possibile selezionare Debug > Riavvia oppure usare i tasti di scelta rapida Ctrl + Shift + F5.
La funzione Riavvia è più efficiente anziché arrestare l'app e avviare di nuovo il debugger.
Quando si seleziona Riavvia, il debugger si interrompe al primo punto di interruzione rilevato durante l'esecuzione. In questo esempio il debugger si arresta di nuovo nel punto di interruzione impostato all'interno del ciclo for
.
Esaminare le variabili con i suggerimenti sui dati
Le funzionalità che consentono di esaminare le variabili sono uno dei vantaggi più utili dell'uso del debugger. Spesso, quando si esegue il debug di un problema, si sta tentando di individuare se le variabili archiviano i valori previsti in determinati momenti. Visual Studio offre diversi modi per completare questa attività.
Continuare con la sessione di debug:
Mentre il debugger è sospeso sull'istruzione
name += letters[i]
, passa il mouse sulla variabileletters
. Selezionare la freccia di espansione/compressione a sinistra del nome della variabile e visualizzarne le proprietà nel menu a comparsa.La funzionalità suggerimenti dei dati mostra tutti gli elementi contenuti nella variabile. Si noti il valore predefinito
size={10}
:Passare quindi il puntatore del mouse sulla variabile
name
e notare il valore corrente, una stringa vuota (""
).Selezionare F5 (Debug>Continua) alcune volte per iterare più volte attraverso il ciclo
for
. Ogni volta che il debugger si ferma al punto di interruzione, passa il mouse sopra la variabilename
e controlla il valore corrente.Il valore della variabile viene modificato con ogni iterazione del ciclo
for
, che mostra i valori dif
, quindifr
, quindifre
e così via.
Esaminare le variabili con le finestre Auto e Variabili locali
Un altro approccio per esaminare variabili e valori consiste nell'usare le finestre variabili automatiche e variabili locali. Per impostazione predefinita, queste finestre vengono visualizzate sotto l'editor di codice nell'IDE di Visual Studio durante il debug dell'app:
Si noti la finestra Auto sotto l'editor di codice.
Se non viene visualizzata la finestra durante la sessione di debug, selezionare Debug>>Auto di Windows per aprire la finestra.
La finestra auto mostra tutte le variabili usate nella riga corrente o nella riga precedente insieme al loro valore corrente. Tenere presente che specifici linguaggi di programmazione possono illustrare un comportamento univoco per variabili e proprietà. Per altre informazioni, vedere Visual Studio Language Guidance.
Successivamente, osserva la finestra Locals. Per impostazione predefinita, questa finestra è allineata accanto alla finestra Autos.
Se la finestra non viene visualizzata durante la sessione di debug, selezionare Debug>Windows>Locals per aprire la finestra
Nella finestra Variabili locali, espandere la variabile
letters
per mostrare gli elementi che contiene.La finestra Variabili Locali mostra le variabili che si trovano nell'ambito corrente , ovvero nel contesto di esecuzione attuale.
Monitorare una variabile
Se si è interessati a controllare il comportamento di una variabile specifica, è possibile impostare un watch:
Nell'editor di codice fare clic con il pulsante destro del mouse sulla variabile name
e selezionare Aggiungi controllo. La finestra di controllo si apre sotto l'editor di codice. È possibile utilizzare una finestra di osservazione per specificare una variabile (o un'espressione) da monitorare.
Quando si osserva la variabile name
durante l'esecuzione dell'app nel debugger, è possibile visualizzarne la modifica del valore. A differenza delle altre finestre delle variabili, la finestra Watch mostra sempre le variabili che stai osservando. Quando una variabile osservata non è nell'ambito, il nome della variabile viene disattivato.
Esaminare lo stack di chiamate
La finestra dello stack di chiamate
Mentre il debugger è in pausa nel ciclo
for
, selezionare la finestra Call Stack per visualizzare la struttura delle chiamate corrente.Se non viene visualizzata la finestra durante la sessione di debug, selezionare Debug>Windows>Stack di chiamate per aprire la finestra.
Selezionare F11 (Debug>Step Into) alcune volte fino a quando non viene visualizzata la sospensione del debugger nel metodo
SendMessage
.Osserva di nuovo la finestra stack di chiamate:
Nella finestra stack di chiamate la riga superiore mostra la funzione corrente (il metodo
SendMessage
in questa app). La seconda riga mostra che il metodoSendMessage
è stato chiamato dal metodomain
e così via.
Lo stack di chiamate è un buon modo per esaminare e comprendere il flusso di esecuzione di un'app:
Fare doppio clic su una riga di codice per passare al codice sorgente. Questa azione modifica anche l'ambito corrente sottoposto a ispezione dal debugger, ma non fa avanzare il debugger.
Accedi ai menu di scelta rapida per gli elementi di programmazione nella finestra stack di chiamate. Ad esempio, è possibile inserire punti di interruzione nelle funzioni specificate, avanzare il debugger usando Esegui al cursoree esaminare il codice sorgente. Per altre informazioni, vedere Visualizzare lo stack di chiamate e usare la finestra Stack di chiamate nel debugger.
Modificare il flusso di esecuzione
Un'altra funzionalità del debugger in Visual Studio è la possibilità di modificare il flusso di esecuzione dell'app:
Selezionare F11 (Debug>Passa dentro) due volte per eseguire la funzione
std::wcout
.Mentre il debugger è in pausa nella chiamata del metodo
SendMessage
, selezionare e trascinare la freccia gialla (il puntatore di esecuzione) alla sinistra della variabile, quindi spostare la freccia all'istruzione di codice precedente,std::wcout
.Selezionare di nuovo F11.
Il debugger esegue nuovamente la funzione
std::wcout
. È possibile tenere traccia del processo nell'output del terminale.Modificando il flusso di esecuzione, è possibile eseguire operazioni come testare percorsi di esecuzione di codice diversi o rieseguire il codice senza riavviare il debugger.
Attenzione
Prestare attenzione quando si lavora con questa funzionalità. Quando si seleziona la freccia gialla, Visual Studio visualizza un avviso nel tooltip che indica che la modifica dell'esecuzione può avere conseguenze impreviste. A seconda dello scenario, potrebbero essere visualizzati anche altri avvisi. Tenere presente che lo spostamento del puntatore non può ripristinare lo stato precedente dell'applicazione.
Selezionare F5 per completare l'esecuzione dell'app.