Générer du code source à partir d’assemblys .NET lors du débogage
Lorsque vous déboguez une application .NET, vous pouvez constater que vous souhaitez afficher le code source que vous n’avez pas. Par exemple, l’arrêt sur une exception ou l’utilisation de la pile des appels pour accéder à un emplacement source.
Remarque
- La génération de code source (décompilation) est disponible uniquement pour les applications .NET et est basée sur le projet ILSpy open source.
- La décomposition est disponible uniquement dans Visual Studio 2019 16.5 et versions ultérieures.
- L’application de l’attribut SuppressIldasmAttribute à un assembly ou un module empêche Visual Studio de tenter de décomposer. Bien que l’attribut soit obsolète dans .NET 6 et versions ultérieures, Visual Studio respecte l’attribut.
Générer du code source
Quand vous déboguez et que le code source n’est pas disponible, Visual Studio affiche le document Source introuvable ou, si vous n’avez pas de symboles pour l’assembly, le document Aucun symbole chargé. Les deux documents ont une option Décompiler le code source qui génère du code C# pour l’emplacement actuel. Le code C# généré peut ensuite être utilisé comme n’importe quel autre code source. Vous pouvez afficher le code, inspecter les variables, définir des points d’arrêt, et ainsi de suite.
Aucun symbole chargé
L’illustration suivante montre le message Aucun symbole chargé.
Capture d'écran
Source introuvable
L’illustration suivante montre le message source introuvable.
Capture d’écran
Code de décompilation automatique
À compter de Visual Studio 2022 version 17.7, le débogueur Visual Studio prend en charge la décompilation automatique du code .NET externe. Vous pouvez décompiler automatiquement en entrant dans le code externe ou lors de l’utilisation de la fenêtre Pile des appels.
Si vous entrez dans du code implémenté en externe, le débogueur le décompile automatiquement et affiche la position actuelle d’exécution. Si vous souhaitez passer au code externe, désactivez Uniquement mon code.
Vous pouvez décompiler à partir de la fenêtre Pile des appels sans désactiver Uniquement mon Code.
Pour décompiler automatiquement à partir de la fenêtre Pile des appels :
Lors du débogage avec la fenêtre Pile des appels ouverte, sélectionnez Afficher le code externe.
Dans la fenêtre Pile des appels, double-cliquez sur n’importe quel cadre de pile. Le débogueur décompose le code, puis accède directement au point d’exécution actuel.
Tout le code décompilé est également affiché sous le nœud Sources externes dans l’Explorateur de solutions, ce qui facilite la navigation dans les fichiers externes si nécessaire.
Vous pouvez déboguer le code décompilé et définir des points d’arrêt.
Pour désactiver la décompilation automatique du code externe, accédez à Outils > Options > Débogage > Général et désélectionnez Décompiler automatiquement la source si nécessaire (géré uniquement).
Générer et incorporer des sources pour un assembly
En plus de générer du code source pour un emplacement spécifique, vous pouvez générer tout le code source d’un assembly .NET donné. Pour effectuer cette tâche, accédez à la fenêtre Modules et, dans le menu contextuel d’une assembly .NET, sélectionnez ensuite la commande Décompiler la source en fichier de symboles. Visual Studio génère un fichier de symboles pour l’assembly, puis incorpore la source dans le fichier de symboles. Dans une étape ultérieure, vous pouvez extraire le code source incorporé.
Extraire et afficher le code source incorporé
Vous pouvez extraire des fichiers sources incorporés dans un fichier de symboles à l’aide de la commande Extraire le code source dans le menu contextuel de la fenêtre modules.
Les fichiers sources extraits sont ajoutés à la solution en tant que fichiers divers. La fonctionnalité de fichiers divers est désactivée par défaut dans Visual Studio. Vous pouvez activer cette fonctionnalité à partir des outils >Options>environnement>Documents>Afficher les fichiers divers dans l'Explorateur de solutions case à cocher. Si cette fonctionnalité n’est pas activée, vous ne pouvez pas ouvrir le code source extrait.
Les fichiers sources extraits apparaissent dans les fichiers divers de l’Explorateur de solutions .
SourceLink
Pour les bibliothèques .NET ou pour les packages NuGet activés pour SourceLink, vous pouvez également passer au code source, définir des points d’arrêt et utiliser toutes les fonctionnalités du débogueur. Pour plus d’informations, consultez Activer le débogage et les diagnostics avec source Link et Améliorer la productivité au moment du débogage avec sourceLink.
Limitations connues
Nécessite le mode arrêt
La génération de code source à l’aide de la décompilation est possible uniquement lorsque le débogueur est en mode arrêt et que l’application est suspendue. Par exemple, Visual Studio entre en mode arrêt lorsqu’il atteint un point d’arrêt ou une exception. Vous pouvez facilement faire en sorte que Visual Studio s'arrête lors de la prochaine exécution de votre code à l’aide de la commande "Arrêter tout" (icône).
Limitations de la décompilation
La génération de code source à partir du format intermédiaire (IL) utilisé dans les assemblys .NET présente certaines limitations inhérentes. Par conséquent, le code source généré ne ressemble pas au code source d’origine. La plupart des différences se trouvent dans les emplacements où les informations contenues dans le code source d’origine ne sont pas nécessaires au moment de l’exécution. Par exemple, les informations telles que les espaces blancs, les commentaires et les noms des variables locales ne sont pas nécessaires au moment de l’exécution. Nous vous recommandons d’utiliser la source générée pour comprendre comment le programme s’exécute et non comme remplacement du code source d’origine.
Déboguer des assemblys optimisés ou Release
Lors du débogage du code décompilé à partir d’un assembly compilé à l’aide d’optimisations du compilateur, vous pouvez rencontrer les problèmes suivants :
- Les points d’arrêt pourraient ne pas toujours être liés à l’emplacement d’approvisionnement correspondant.
- L’exécution pas à pas pourrait ne pas toujours atteindre l’emplacement approprié.
- Les variables locales peuvent ne pas avoir de noms précis.
- Certaines variables peuvent ne pas être disponibles pour l’évaluation.
Pour plus d’informations, consultez le problème GitHub : Intégration d’ICSharpCode.Decompiler au Débogueur VS.
Fiabilité de la décompilation
Un pourcentage relativement faible de tentatives de décompilation peut entraîner un échec. Ce comportement est dû à une erreur de référence null de point de séquence dans ILSpy. Nous avons atténué la défaillance en interceptant ces problèmes et en échouant de manière élégante la tentative de décompilation.
Pour plus d’informations, consultez le problème GitHub : Intégration d’ICSharpCode.Decompiler au Débogueur VS.
Limitations avec du code asynchrone
Les résultats de la décomposition des modules avec des modèles de code asynchrone/await peuvent être incomplets ou échouer entièrement. L’implémentation ILSpy des modèles async/await et des machines à états yield n’est que partiellement effectuée.
Vous trouverez plus d’informations dans le problème GitHub : état du générateur PDB.
Juste mon code
Le paramètre JMC (Just My Code) autorise Visual Studio à sauter les appels système, cadre, bibliothèque et autres appels non-utilisateur. Pendant une session de débogage, la fenêtre Modules affiche les modules de code que le débogueur traite comme Mon code (code utilisateur).
La décompilation des modules optimisés ou de mise en production produit du code non-utilisateur. Si le débogueur s’arrête dans votre code non-utilisateur décompilé, par exemple, la fenêtre Aucune source s’affiche. Pour désactiver uniquement mon code, accédez à Outils>Options (ou Débogage>Options) >Débogage>Général, puis désélectionnez Activer uniquement mon code.
Sources extraites
Le code source extrait d’un assembly présente les limitations suivantes :
- Le nom et l’emplacement des fichiers générés ne sont pas configurables.
- Les fichiers sont temporaires et supprimés par Visual Studio.
- Les fichiers sont placés dans un dossier unique et la hiérarchie des dossiers des sources d'origine n'est pas conservée.
- Le nom de chaque fichier contient un hachage de somme de contrôle du fichier.
Le code généré est C# uniquement
La décompilation génère uniquement des fichiers de code source en C#. Il n’existe aucune option permettant de générer des fichiers dans une autre langue.