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 ILSpy open source.
  • 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 Source Not Found o se non si dispone di simboli per l'assembly, il documento No Symbols Loaded ( Nessun simbolo caricato). Entrambi i documenti hanno un'opzione Decompile source code 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 No Symbols Loaded .

Screenshot of no symbol loaded document

Origine non trovata

La figura seguente mostra il messaggio Source Not Found .

Screenshot of source not found document

Codice autodecompile

A partire da Visual Studio 2022 versione 17.7, il debugger di Visual Studio supporta la correzione automatica del codice .NET esterno. È possibile eseguire automaticamente il completamento automatico quando si esegue l'istruzione in codice esterno o quando si usa la finestra Stack di 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, Just My Code deve essere disabilitato.

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

Per eseguire automaticamente il completamento dalla finestra Stack di chiamate:

  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 stack frame. Il debugger decompila il codice e quindi passa direttamente al punto di esecuzione corrente.

    Screenshot of Call Stack window showing external code.

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

    Screenshot of External Sources node showing decompiled assemblies.

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

Per disabilitare la decompilazione automatica del codice esterno, passare a Strumenti Opzioni debug Generale e deselezionare Decompilazione automatica per l'origine quando necessario (solo gestito).To disable the automatic decompilation of external code, go to Tools Options Debugging > General and deselect decompile to source when needed (managed only).>>

Generare e incorporare origini per un assembly

Oltre a generare codice sorgente per una posizione specifica, è possibile generare tutto il codice sorgente per un determinato assembly .NET. A tale scopo, passare alla finestra Moduli e dal menu di scelta rapida di un assembly .NET e quindi selezionare il comando Decompile Source to Symbol File (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 of assembly context menu in modules window with decompile source command.

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 di scelta rapida della finestra Moduli .

Screenshot of assembly context menu in modules window with extract sources command.

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

Screenshot of tools option page with miscellaneous files option enabled.

I file di origine estratti vengono visualizzati nei file esterni in Esplora soluzioni.

Screenshot of solution explorer with miscellaneous files.

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 il collegamento all'origine 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 (Break all icon).

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 versione

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'istruzione potrebbe non sempre passare alla posizione corretta.
  • Le variabili locali potrebbero non avere nomi accurati.
  • Alcune variabili potrebbero non essere disponibili per la valutazione.

Per altre informazioni, vedere il problema di GitHub: integrazione ICSharpCode.Decompiler in VS Debugger.

Decompilazione affidabilità

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 altre informazioni, 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 non riescono 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.

Just My Code

L'impostazione Just My Code (JMC) consente a Visual Studio di eseguire il passaggio di sistema, framework, libreria 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 Opzioni strumenti> (o Opzioni di debug>)> Debug>generale e quindi deselezionare Abilita Just My Code.

Origini 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 in qualsiasi gerarchia di cartelle non usata dalle origini originali.
  • 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.