Informazioni sul debugger .NET in Visual Studio Code

Completato

Nell'unità precedente si è appreso che un debugger consente di controllare l'esecuzione del programma e osservarne lo stato. In questa sezione si apprenderà come eseguire entrambe le operazioni in Visual Studio Code.

Verrà descritto come configurare il debugger di Visual Studio Code per l'uso con .NET.

Configurare Visual Studio Code per il debug di .NET

Quando si apre un file C# in Visual Studio Code per la prima volta, viene visualizzata la richiesta di installare le estensioni consigliate per C#.

Screenshot of Visual Studio Code prompt to install the C# extension.

Visual Studio Code installa l'estensione C# e visualizza un'ulteriore richiesta di aggiungere gli asset necessari per la compilazione e il debug del progetto.

Screenshot of Visual Studio Code prompt to add required assets to build and debug your .NET project.

Nota

Il supporto del linguaggio C# in Visual Studio Code è un'installazione facoltativa da Marketplace. Visual Studio Code chiede automaticamente di installare questa estensione quando si apre un file C#, se non è stata ancora installata. Se si verificano problemi durante la compilazione o il debug dell'applicazione .NET in Visual Studio Code, è necessario verificare che nel progetto siano presenti gli asset necessari per il supporto del linguaggio C#.

Punti di interruzione

Come si è appreso nell'unità precedente, un debugger consente di analizzare e controllare l'esecuzione del programma. Quando si avvia il debugger di Visual Studio Code, il debugger inizia immediatamente a eseguire il codice. Poiché il codice viene eseguito rapidamente, è necessario essere in grado di sospendere il programma in corrispondenza di qualsiasi istruzione. A tale scopo, si useranno i punti di interruzione.

È possibile aggiungere un punto di interruzione in Visual Studio Code facendo clic a sinistra del numero di riga, in corrispondenza della riga che si vuole interrompere. Quando il punto di interruzione è abilitato, viene visualizzato un cerchio rosso. Per rimuoverlo, fare di nuovo clic sul cerchio rosso.

Screenshot of a breakpoint added in the Visual Studio Code editor window.

Se si fa clic con il pulsante destro del mouse per aggiungere un punto di interruzione, è anche possibile selezionare Aggiungi punto di interruzione condizionale. Questo tipo di punto di interruzione speciale consente di immettere una condizione per interrompere l'esecuzione. Questo punto di interruzione sarà attivo solo quando viene soddisfatta la condizione specificata. È anche possibile modificare un punto di interruzione esistente facendo clic con il pulsante destro del mouse su di esso e selezionando Modifica punto di interruzione.

Screenshot of setting a conditional breakpoint in Visual Studio Code.

Panoramica del debugger di Visual Studio Code

Dopo avere configurato i punti di interruzione e avere avviato l'app, sullo schermo vengono visualizzati nuovi controlli e riquadri informazioni.

Screenshot of Visual Studio Code debugger overview.

  1. Controlli di avvio del debugger
  2. Stato delle variabili
  3. Stato delle variabili controllate
  4. Stack di chiamate corrente
  5. Punti di interruzione
  6. Controlli di esecuzione
  7. Passaggio di esecuzione corrente
  8. Console di debug

Controlli di avvio del debugger

Nella parte superiore della barra laterale sono disponibili i controlli di avvio:

Screenshot of Visual Studio Code debug sidebar controls.

  1. Avviare il debug.
  2. Selezionare la configurazione di avvio attiva.
  3. Modificare il file launch.json. Crearlo, se necessario.
  4. Aprire il terminale di debug.

Visualizzare e modificare lo stato delle variabili

Quando si analizza la causa di un difetto del programma, controllare lo stato delle variabili per cercare modifiche impreviste. A tale scopo, è possibile usare il pannello Variabili.

Le variabili vengono visualizzate organizzate per ambito:

  • Le variabili locali sono accessibili nell'ambito corrente, in genere la funzione corrente.
  • Le variabili globali sono accessibili da qualsiasi punto del programma. Sono inclusi anche gli oggetti di sistema del runtime JavaScript, quindi non bisogna sorprendersi se sono presenti parecchi elementi.
  • Le variabili di chiusura sono accessibili dalla chiusura corrente, se presente. Una chiusura combina l'ambito locale di una funzione con quello della funzione esterna a cui appartiene.

È possibile espandere gli ambiti e le variabili selezionando la freccia. Quando si espandono gli oggetti, vengono visualizzate tutte le proprietà definite al loro interno.

È possibile modificare il valore di una variabile facendo doppio clic sulla variabile.

Passando il mouse su un parametro di funzione o una variabile direttamente nella finestra dell'editor, è anche possibile visualizzarne in anteprima il valore.

Screenshot of variable hover during debugging.

Controllare le variabili

Può essere noioso cercare uno stato di variabile ogni volta che si vuole monitorarlo tra le funzioni temporali o diverse. A tale scopo, è utile usare il pannello Espressione di controllo.

È possibile selezionare il pulsante Più per immettere il nome di una variabile o un'espressione da controllare. In alternativa, è possibile fare clic con il pulsante destro del mouse su una variabile nel pannello Variabili e selezionare Aggiungi a espressione di controllo.

Tutte le espressioni all'interno del pannello espressioni di controllo vengono aggiornate automaticamente durante l'esecuzione del codice.

Stack di chiamate

Ogni volta che il programma immette una funzione, viene aggiunta una voce allo stack di chiamate. Quando l'applicazione diventa complessa e sono presenti funzioni chiamate all'interno di altre funzioni molte volte, lo stack di chiamate rappresenta il tracciato delle chiamate di funzione.

È utile per trovare l'origine di un'eccezione. Se si verifica un arresto anomalo imprevisto del programma, nella console viene spesso visualizzato un errore simile al seguente:

Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at OrderProcessor.OrderQueue.ProcessNewOrders(String[] orderIds) in C:\Users\Repos\OrderProcessor\OrderQueue.cs:line 12
   at OrderProcessor.Program.Main(String[] args) in C:\Users\Repos\OrderProcessor\Program.cs:line 9

Il gruppo di righe at [...] sotto il messaggio di errore è detto analisi dello stack. L'analisi dello stack specifica il nome e l'origine di ogni funzione che è stata chiamata prima di terminare con l'eccezione. Tuttavia, può essere difficile da decifrare, poiché include anche funzioni interne del runtime .NET.

In questo caso, è utile usare il pannello Stack di chiamate di Visual Studio Code. Filtra le informazioni indesiderate per visualizzare solo le funzioni rilevanti dal codice per impostazione predefinita. È quindi possibile rimuovere questo stack di chiamate per individuare da dove è stata originata l'eccezione.

Pannello Punti di interruzione

Nel pannello Punti di interruzione è possibile visualizzare e attivare/disattivare tutti i punti di interruzione inseriti nel codice. È anche possibile attivare/disattivare le opzioni per l'interruzione in corrispondenza di eccezioni rilevate o non rilevate. È possibile usare il pannello Punti di interruzione per esaminare lo stato del programma e risalire all'origine di un'eccezione usando lo stack di chiamate quando se ne verifica una.

Controllare l'esecuzione

È possibile controllare il flusso di esecuzione del programma usando questi controlli.

Screenshot of Visual Studio Code debugger execution controls.

Da sinistra a destra, i controlli sono i seguenti:

  • Continua o Sospendi esecuzione: Se l'esecuzione è sospesa, continuerà finché non viene raggiunto il punto di interruzione successivo. Se il programma è in esecuzione, il pulsante cambia in Sospendi esecuzione, utilizzabile per sospendere l'esecuzione.
  • Passa oltre: Esegue l'istruzione del codice successiva nel contesto corrente.
  • Esegui l'istruzione: Simile a Esegui istruzione/routine, ma se l'istruzione successiva è una chiamata di funzione, passa alla prima istruzione del codice di questa funzione (analogamente al comando step).
  • Esci dall’istruzione: Se ci si trova all'interno di una funzione, esegue il codice rimanente di questa funzione e torna all'istruzione dopo la chiamata di funzione iniziale (analogamente al comando out).
  • Riavvia: Riavvia il programma dall'inizio.
  • Arresta: Terminare l'esecuzione e uscire dal debugger.

Usare la console di debug

La console di debug può essere visualizzata o nascosta premendo CTRL+MAIUSC+Y per Windows e Linux. Selezionare CMD+MAIUSC+Y per Mac. La console di debug può essere usata per visualizzare i log della console dell'applicazione. Può essere usata anche per valutare le espressioni o eseguire il codice nel contenuto di esecuzione corrente, come comandi o nomi di variabili nel debugger predefinito di .NET.

È possibile immettere un'espressione .NET nel campo di input nella parte inferiore della console di debug e quindi premere INVIO per valutarla. Il risultato verrà visualizzato direttamente nella console.

Screenshot of Visual Studio Code debug console.

Con la console di debug è possibile controllare rapidamente il valore di una variabile, testare una funzione con valori diversi o modificare lo stato corrente.

Nota

Anche se la console di debug è molto utile per l'esecuzione e la valutazione del codice .NET, può risultare poco confusa quando si tenta di eseguire o eseguire il debug di un'applicazione console .NET perché la console di debug non accetta l'input del terminale per un programma in esecuzione.

Per gestire l'input del terminale durante il debug, è possibile usare il terminale integrato (una delle finestre di Visual Studio Code) o un terminale esterno. Per questa esercitazione si usa il terminale integrato.

  1. Aprire .vscode/launch.json.

  2. Modificare l'impostazione console in integratedTerminal da:

    "console": "internalConsole",
    

    Con:

    "console": "integratedTerminal",
    
  3. Salva le modifiche.

Nell'unità successiva si apprenderà come usare il debugger per correggere il bug nel codice di Fibonacci illustrato in precedenza.