Leggere in inglese

Condividi tramite


Generare codice sorgente da assembly .NET durante il debug

Quando si esegue il debug di un'applicazione .NET, è possibile che si voglia visualizzare il codice sorgente non disponibile. Ad esempio, l'interruzione di un'eccezione o l'uso dello stack di chiamate per passare a un percorso di origine.

Nota

  • La generazione di codice sorgente (decompilazione) è disponibile solo per le applicazioni .NET ed è basata sul progetto open source ILSpy.
  • La decompilazione è disponibile solo in Visual Studio 2019 16.5 e versioni successive.
  • L'applicazione dell'attributo SuppressIldasmAttribute a un assembly o a un modulo impedisce a Visual Studio di tentare la decompilazione. Anche se l'attributo è obsoleto in .NET 6 e versioni successive, Visual Studio rispetta l'attributo .

Generare il codice sorgente

Quando si esegue il debug e non è disponibile alcun codice sorgente, Visual Studio visualizza il documento Origine non trovata oppure, se non sono presenti simboli per l'assembly, il documento Nessun simbolo caricato. Entrambi i documenti hanno un'opzione di Decompilazione del codice sorgente che genera codice C# per la posizione corrente. Il codice C# generato può quindi essere usato esattamente come qualsiasi altro codice sorgente. È possibile visualizzare il codice, controllare le variabili, impostare punti di interruzione e così via.

Nessun simbolo caricato

La figura seguente mostra il messaggio Nessun simbolo caricato.

Screenshot del documento senza simbolo caricato

Origine non trovata

La figura seguente mostra il messaggio di Origine non trovata.

Screenshot del documento di origine non trovato

Decompilazione automatica del codice

A partire da Visual Studio 2022 versione 17.7, il debugger di Visual Studio supporta la correzione automatica del codice .NET esterno. È possibile decompilare automaticamente quando si procede nel codice esterno o quando si usa la finestra dello stack delle chiamate.

Se si esegue un'istruzione nel codice implementato esternamente, il debugger lo decompila automaticamente e visualizza il punto di esecuzione corrente. Se si vuole eseguire l'istruzione nel codice esterno, disabilitare Just My Code.

È possibile decompilare dalla finestra Stack di chiamate senza disabilitare Just My Code.

Per decompilare automaticamente dalla finestra Call Stack:

  1. Durante il debug con la finestra Stack di chiamate aperta, selezionare Mostra codice esterno.

  2. Nella finestra Stack di chiamate fare doppio clic su qualsiasi frame dello stack. Il debugger decompila il codice e quindi passa direttamente al punto di esecuzione corrente.

    Screenshot della finestra Call Stack che mostra il codice esterno.

    Tutto il codice decompilato viene visualizzato anche nel nodo Origini esterne in Esplora soluzioni, semplificando l'esplorazione dei file esterni, se necessario.

    Screenshot del nodo

    È possibile eseguire il debug del codice decompilato e impostare punti di interruzione.

Per disabilitare la decompilazione automatica del codice esterno, andare su Strumenti > Opzioni > Debugging > Generale e deselezionare Decompila automaticamente all'origine quando necessario (solo per codice gestito).

Generare e incorporare origini per un assemblaggio

Oltre a generare codice sorgente per una posizione specifica, è possibile generare tutto il codice sorgente per un determinato assembly .NET. Per eseguire questa attività, passare alla finestra Moduli e, dal menu di scelta rapida di un assembly .NET, selezionare il comando Decompile Source to Symbol File. Visual Studio genera un file di simboli per l'assembly e quindi incorpora l'origine nel file di simboli. In un passaggio successivo è possibile estrarre il codice sorgente incorporato.

Screenshot del menu di scelta rapida dell'assembly nella finestra moduli con il comando di decompilazione del codice sorgente.

Estrarre e visualizzare il codice sorgente incorporato

È possibile estrarre i file di origine incorporati in un file di simboli usando il comando Estrai Codice Sorgente nel menu contestuale della finestra Moduli.

Screenshot del menu contestuale dell'assembly nella finestra moduli con il comando estrai sorgenti.

I file di origine estratti vengono aggiunti alla soluzione come file vari. La funzionalità file vari è disattivata per impostazione predefinita in Visual Studio. È possibile abilitare questa funzionalità dalla casella di controllo Strumenti>Opzioni>Ambiente>Documenti>Mostra file esterni in Esplora soluzioni. Se questa funzionalità non è abilitata, non è possibile aprire il codice sorgente estratto.

Schermata della pagina delle opzioni degli strumenti con l'opzione file vari abilitata.

I file di origine estratti vengono visualizzati nei file vari nell'Esplora soluzioni .

Screenshot di Esplora soluzioni con file vari.

Per le librerie .NET o per i pacchetti NuGet abilitati per SourceLink, è anche possibile eseguire istruzioni nel codice sorgente, impostare punti di interruzione e usare tutte le funzionalità del debugger. Per altre informazioni, vedere Abilitare il debug e la diagnostica con SourceLink e Migliorare la produttività in fase di debug con SourceLink.

Limitazioni note

Richiede la modalità di interruzione

La generazione di codice sorgente tramite la decompilazione è possibile solo quando il debugger è in modalità di interruzione e l'applicazione viene sospesa. Ad esempio, Visual Studio passa alla modalità di interruzione quando raggiunge un punto di interruzione o un'eccezione. È possibile attivare facilmente Visual Studio per interrompere la successiva esecuzione del codice usando il comando Interrompi tutto (Interrompi tutte le icone).

Limitazioni di decompilazione

La generazione di codice sorgente dal formato intermedio (IL) usato negli assembly .NET presenta alcune limitazioni intrinseche. Di conseguenza, il codice sorgente generato non è simile al codice sorgente originale. La maggior parte delle differenze si trova nelle posizioni in cui le informazioni nel codice sorgente originale non sono necessarie in fase di esecuzione. Ad esempio, le informazioni come spazi vuoti, commenti e nomi delle variabili locali non sono necessarie in fase di esecuzione. È consigliabile usare l'origine generata per comprendere come il programma è in esecuzione e non come sostituzione del codice sorgente originale.

Eseguire il debug di assembly ottimizzati o di rilascio

Durante il debug del codice decompilato da un assembly compilato tramite ottimizzazioni del compilatore, potrebbero verificarsi i problemi seguenti:

  • I punti di interruzione potrebbero non essere sempre associati alla posizione di origine corrispondente.
  • L'avanzamento potrebbe non sempre spostarsi alla posizione corretta.
  • Le variabili locali potrebbero non avere nomi accurati.
  • Alcune variabili potrebbero non essere disponibili per la valutazione.

Per altri dettagli, vedere il problema di GitHub: Integrazione ICSharpCode.Decompiler in VS Debugger.

Affidabilità della decompilazione

Una percentuale relativamente piccola di tentativi di decompilazione può causare un errore. Questo comportamento è dovuto a un errore di riferimento null del punto di sequenza in ILSpy. L'errore è stato risolto intercettando questi problemi ed eseguendo correttamente il tentativo di decompilazione.

Per altri dettagli, vedere il problema di GitHub: integrazione ICSharpCode.Decompiler in VS Debugger.

Limitazioni con codice asincrono

I risultati della decompilazione dei moduli con modelli di codice asincroni/await possono essere incompleti o fallire completamente. L'implementazione ILSpy di async/await e yield state-machines è implementata solo parzialmente.

Altri dettagli sono disponibili nel problema di GitHub: stato del generatore PDB.

Solo il Mio Codice

L'impostazione Just My Code (JMC) consente a Visual Studio di ignorare le chiamate del sistema, del framework, delle librerie e altre chiamate non utente. Durante una sessione di debug, la finestra Moduli mostra i moduli di codice che il debugger considera come Codice personale (codice utente).

La decompilazione dei moduli ottimizzati o di versione produce codice non utente. Se il debugger si interrompe nel codice non utente decompilato, ad esempio, viene visualizzata la finestra Nessuna origine. Per disabilitare Just My Code, passare a Tools>Options (o Debug>Options) >Debugging>Generale quindi deselezionare Enable Just My Code.

Fonti estratte

Il codice sorgente estratto da un assembly presenta le limitazioni seguenti:

  • Il nome e il percorso dei file generati non sono configurabili.
  • I file sono temporanei ed eliminati da Visual Studio.
  • I file vengono inseriti in una singola cartella e la gerarchia di cartelle che le fonti originali avevano non viene utilizzata.
  • Il nome del file per ogni file contiene un hash checksum del file.

Il codice generato è solo C#

La decompilazione genera solo file di codice sorgente in C#. Non esiste un'opzione per generare file in nessun'altra lingua.