Lire un dump de plantage avec WinDbg + SOS — Guide pratique d'analyse après la collecte

· Mis à jour le: · · WinDbg, SOS, Dump de plantage, .NET, CSharp, Débogage, PDB, Enquête de bogue, Conseil technique

Un précédent article, « Introduction à la collecte de dumps de plantage Windows », couvrait la partie « collecte » des dumps avec WER LocalDumps, ProcDump et MiniDumpWriteDump. Mais un dump qui a simplement été collecté ne vous apprend rien en soi. Il ne devient une matière d’enquête utile qu’une fois que vous vous êtes réellement plongé dedans pour comprendre quel thread a planté, pourquoi il a planté, ou ce qui retient la mémoire.

Cet article fait suite au volet consacré à la collecte et se concentre exclusivement sur la lecture concrète d’un dump obtenu, avec WinDbg et l’extension SOS. Il couvre l’installation et la configuration des symboles, le chargement de l’extension SOS indispensable pour les applications .NET, ce qu’il faut regarder et comment l’interpréter avec des commandes représentatives comme !clrstack ou !dumpheap -stat, !analyze -v pour les plantages natifs, et enfin le choix entre WinDbg et dotnet-dump analyze, qui permet de s’en passer.

1. L’essentiel d’abord

  • L’outil principal pour l’analyse de dumps est WinDbg (la version actuelle, anciennement appelée WinDbg Preview). Vous pouvez l’obtenir via winget install Microsoft.WinDbg ou depuis le Microsoft Store ; il fonctionne en x64/ARM64 sur Windows 10 Anniversary Update (1607) et ultérieur, ainsi que sur Windows 11.1
  • Même sans symboles (PDB) chargés, des commandes comme !clrstack, !dumpheap -stat ou !gcroot fonctionnent directement à partir des métadonnées et des données de tas du CLR. Ce qui est perdu, ce sont les noms de fichiers source et les numéros de ligne côté managé, ainsi que les noms de symboles des frames natifs. Cela dit, si vous voulez remonter jusqu’à la ligne source, c’est une autre histoire : la pratique standard consiste à faire pointer _NT_SYMBOL_PATH à la fois vers le serveur de symboles public de Microsoft et vers l’emplacement de vos propres PDB.2
  • Pour les dumps d’applications .NET (Framework / Core / 5+), les informations managées ne deviennent visibles qu’une fois l’extension SOS chargée. La commande native k (affichage de la pile) seule ne permet pas de suivre le code C#.3
  • Il existe trois types d’enquête représentatifs : en cas d’exception, commencez par !clrstack!pe ; si la mémoire augmente continuellement, commencez par !dumpheap -stat!gcroot ; pour un plantage natif, commencez par !analyze -v.
  • dotnet-dump analyze est une option qui permet de se passer de WinDbg. La plupart des commandes SOS s’y utilisent telles quelles, mais il ne gère pas les frames de pile natifs. Pour une enquête purement managée, sans DLL native ni COM en jeu, sa mise en place est plus légère.4
  • Les procédures décrites ici concernent la façon de lire un dump, pas de le collecter. Pour la méthode de collecte (WER / ProcDump / MiniDumpWriteDump), reportez-vous à l’article de collecte ; pour la conception d’un dispositif où logs et dumps se recoupent au moment du plantage, voir « Concevoir la conservation des logs et des dumps pour les plantages d’applications Windows ».

2. Installer WinDbg et configurer les symboles

2.1 Installation

La version actuelle de WinDbg peut s’installer de l’une des façons suivantes.1

winget install Microsoft.WinDbg

L’installation via le Microsoft Store donne le même moteur, avec les mêmes commandes, extensions et flux de travail. Après l’installation, la mise à jour est automatique (en arrière-plan pour le Store et l’installation directe, ou via winget upgrade Microsoft.WinDbg pour l’installation winget), donc les différences de comportement entre versions ne posent guère de problème.1

2.2 Ouvrir un dump

windbg -z C:\CrashDumps\MyApp\MyApp_20260702_101500.dmp

-z est l’option qui permet de démarrer en spécifiant un fichier dump. Vous pouvez faire la même chose depuis l’interface graphique via « File > Open Dump File ».

2.3 Configurer le chemin des symboles

L’endroit où le débogueur Windows recherche les fichiers de symboles (PDB) est défini par la variable d’environnement _NT_SYMBOL_PATH, ou par la commande .sympath au sein d’une session.2 En pratique, la base consiste à pointer à la fois vers le serveur de symboles public de Microsoft et vers l’emplacement de vos propres PDB.

.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload
  • .symfix est un raccourci qui configure le chemin vers le serveur de symboles public de Microsoft (https://msdl.microsoft.com/download/symbols), avec un cache local spécifié. Les symboles des DLL standard de l’OS sont automatiquement téléchargés depuis cette source.5
  • .sympath+ ajoute l’emplacement de vos propres PDB au chemin existant. Vous devez fournir vous-même les PDB de votre propre code : ils ne sont pas hébergés sur le serveur de symboles de Microsoft.
  • .reload recharge et permet de vérifier l’état des symboles dans la liste des modules.

Pour une configuration permanente via une variable d’environnement, utilisez la forme suivante. Elle convient mieux à l’analyse automatisée sur CI ou serveur de build.

set _NT_SYMBOL_PATH=srv*C:\Symbols\Microsoft*https://msdl.microsoft.com/download/symbols;C:\Symbols\MyApp

Pour vérifier que les symboles sont correctement lus, affichez la liste des modules avec la commande lm (loaded modules) et contrôlez que le module concerné indique pdb symbols. S’il reste sur deferred, les symboles ne sont pas encore résolus.

3. Charger l’extension SOS

Pour les dumps d’applications .NET, les commandes WinDbg natives seules ne permettent pas de voir le contenu du tas managé, les frames de pile C# ou le contenu des objets exception. C’est ce que comble l’extension SOS (Son of Strike). Elle permet, via ses commandes, d’examiner le tas, de détecter sa corruption, d’afficher les types de données internes au runtime, et de comprendre l’état du code managé en cours d’exécution.3

3.1 Différences selon le runtime

Selon que l’application cible est .NET Framework ou .NET (Core) / .NET 5+, le runtime à charger et la provenance de SOS diffèrent.

Cible Module de runtime Commande de chargement
.NET Framework clr.dll .loadby sos clr
.NET Core / .NET 5+ coreclr.dll .loadby sos coreclr

.loadby est une commande qui recherche et charge la DLL d’extension (sos.dll) présente dans le même répertoire que le module spécifié (clr ou coreclr). Son avantage est de récupérer de manière fiable la version de SOS correspondant à l’environnement où le dump a été collecté, sans avoir à taper le chemin complet.6

À partir de la version 10.0.18317.1001, WinDbg et cdb chargent automatiquement l’extension .NET depuis le Microsoft Extension Gallery dès qu’ils détectent que le processus cible a chargé coreclr.dll (ou libcoreclr.so sous Linux/macOS).6 La commande .loadby ci-dessus est destinée aux cas où le chargement automatique ne se déclenche pas, ou lorsque vous utilisez une version plus ancienne du débogueur.

3.2 Quand SOS est introuvable

Dans les environnements où le chargement automatique ne fonctionne pas, vous pouvez l’installer localement avec l’outil dotnet-sos.

dotnet tool install --global dotnet-sos
dotnet-sos install

Une fois installée, vous pouvez aussi la charger manuellement dans WinDbg comme suit (cela peut être nécessaire avec des débogueurs plus anciens).7

.load %USERPROFILE%\.dotnet\sos\sos.dll

3.3 Vérifier que le chargement a réussi

!sos.help

Vous pouvez aussi essayer !Threads pour une cible de la famille Core, ou !sosstatus pour une cible de la famille Framework : si la commande ne renvoie pas d’erreur et fournit des informations, le chargement a réussi. Si une commande échoue ici avec une erreur du type Unable to find module, la cause est presque toujours une incohérence de chemin de symboles ou de runtime (par exemple une différence de bitness ou de version entre l’environnement où le dump a été collecté et le runtime local). Il n’est pas rare, en pratique, de rester bloqué ici avant même d’atteindre les commandes du chapitre suivant.

4. Lire les exceptions et la pile — !clrstack et !pe

C’est la première étape pour un dump ayant planté sur une exception non gérée.

!threads

Commencez par !Threads (alias clrthreads dans les environnements lldb) pour lister les threads managés et vérifier la colonne Exception de chacun.8 Si un thread porte une exception, basculez sur ce thread.

~5s
!clrstack

!CLRStack affiche une pile d’appels du code managé uniquement.9 Pour voir aussi les arguments et les variables, ajoutez -a (raccourci qui combine -l et -p).

!clrstack -a
  • Si des méthodes de votre propre code apparaissent, vous pouvez directement lire où et par quel chemin d’appel le plantage s’est produit. Le fait de voir les noms de fichiers source et les numéros de ligne dépend du bon chargement des symboles (chapitre 2). CLRStack énumère les frames managés directement à partir des métadonnées du CLR, si bien que la présence ou non de symboles n’a aucune incidence sur l’affichage des frames. Quand les symboles manquent, ce qui est perdu, ce sont uniquement le nom du fichier source et le numéro de ligne — le frame lui-même n’est jamais omis.9
  • Si aucun frame de votre propre code n’apparaît, ne soupçonnez pas un manque de symboles, mais plutôt les causes suivantes : le thread sélectionné est en réalité un autre thread sans exception (erreur de sélection du thread), le plantage a eu lieu uniquement côté natif et aucun frame managé n’existe donc, ou encore le type de dump (Mini, par exemple) ne contient pas suffisamment d’informations de pile à cet instant.

Examinez ensuite l’objet exception lui-même.

!pe

!PrintException (abrégé !pe) affiche, si aucune adresse n’est indiquée, la dernière exception levée sur le thread courant. Vous obtenez le nom du type, le message, les exceptions internes (affichées avec -nested) et même la chaîne de la pile d’appels.10 Plus le nom du type est peu parlant à lui seul — comme System.NullReferenceException — plus il faut le confronter aux valeurs des variables locales visibles via !clrstack -a.

5. Suivre le tas et les fuites — !dumpheap -stat et !gcroot

C’est la commande centrale pour les enquêtes du type « la mémoire augmente peu à peu, et l’application plante au bout de quelques heures ou quelques jours ». La distinction préalable entre attente de GC et véritable fuite a été détaillée dans « Distinguer l’attente du GC d’une fuite de mémoire en .NET ». Cet article en est la suite : il correspond à la partie où l’on lit un seul dump pour aller jusqu’à identifier ce qui retient la mémoire.

!dumpheap -stat

L’option -stat affiche uniquement un résumé statistique du tas managé. Les types sont classés à peu près par ordre décroissant de nombre d’instances et de taille totale, ce qui permet d’identifier d’abord « le type qui domine en volume ».11 En pratique, on rencontre surtout deux profils :

  • Une classe métier elle-même croît (par exemple des centaines de milliers d’instances de MyApp.Models.Customer) — une référence forte la retient quelque part
  • Seuls System.String ou des tableaux sont anormalement nombreux — c’est souvent dû aux données internes d’une classe métier apparaissant plus haut dans la liste ; avant d’examiner les instances individuelles, il est souvent plus rapide de soupçonner d’abord la classe métier elle-même

Une fois la cible identifiée, récupérez les adresses des instances individuelles.

!dumpheap -type MyApp.Models.Customer

Puis étudiez pourquoi cet objet n’a pas été récupéré par le GC et continue d’exister.

!gcroot 000001a2b3c4d5e0

!GCRoot recherche dans l’ensemble du tas managé et de la table des handles, et recense les racines (variables de pile, champs statiques, handles GC, etc.) qui atteignent l’objet indiqué.12 Si la sortie montre un champ statique utilisé pour un cache ou un abonnement à un gestionnaire d’événements, c’est un suspect de premier plan pour un désabonnement oublié. Le code suivant, qui « laisse tout dans un cache sans jamais libérer », en est un exemple typique :

public static class CustomerCache
{
    // Dictionnaire statique sans mécanisme de libération — il ne fait que croître
    private static readonly Dictionary<int, Customer> _cache = new();

    public static void Add(Customer c) => _cache[c.Id] = c;
}

Si un conteneur statique comme CustomerCache apparaît dans la sortie de !gcroot, c’est un élément à prendre en compte pour envisager, côté code, une durée de vie limitée, un nombre maximal d’entrées, ou un passage à WeakReference.11

6. Analyse automatique des plantages natifs — !analyze -v

Pour les plantages natifs (violation d’accès, etc.) impliquant des DLL C++, du COM ou un SDK tiers, commencez toujours par cette commande.

!analyze -v

!analyze est une commande d’extension qui effectue une analyse automatique du plantage ou de l’exception ; l’option -v donne un affichage détaillé.13 Trois éléments méritent particulièrement votre attention dans la sortie :

  • EXCEPTION_CODE / BUGCHECK_STR : le type d’anomalie (violation d’accès, dépassement de pile, etc.)
  • FAULTING_IP / FOLLOWUP_IP : l’adresse de l’instruction qui a effectivement provoqué le plantage, ainsi que le module et la fonction correspondants
  • MODULE_NAME / IMAGE_NAME : si l’endroit du plantage se trouve dans votre propre module ou dans une DLL tierce

Si le plantage se produit dans une DLL fournisseur plutôt que dans votre propre module, il faudrait le PDB du fournisseur pour aller plus loin (généralement impossible à obtenir). En pratique, l’issue réaliste consiste à remonter jusqu’à l’appelant (les derniers arguments passés par votre propre code) et à vérifier si les valeurs transmises étaient cohérentes. Consultez le champ STACK_TEXT de !analyze -v pour voir quel appel votre code venait de faire juste avant le plantage.

!analyze s’utilise aussi sur des dumps autres que ceux d’exceptions. En cas de suspicion de hang, sélectionnez le thread concerné puis exécutez la commande suivante, qui analyse les relations de blocage entre threads.

!analyze -hang

7. Une option sans WinDbg — dotnet-dump analyze

Si vous souhaitez examiner uniquement du code managé .NET Core / .NET 5+ (sans DLL native ni COM impliqués), dotnet-dump, plus léger que WinDbg, est aussi une option.

dotnet tool install --global dotnet-dump
dotnet-dump analyze C:\CrashDumps\MyApp\MyApp_20260702_101500.dmp

La sous-commande analyze ouvre une session interactive avec SOS préinstallé, où vous pouvez utiliser directement, sans le préfixe !, la plupart des commandes présentées jusqu’ici — clrstack, dumpheap, gcroot, etc.4

Voici un repère pour choisir entre les deux :

Aspect WinDbg + SOS dotnet-dump analyze
Frames de pile natifs Visibles Non visibles (managé uniquement)4
Analyse native automatique via !analyze -v Disponible Non disponible
Dumps Linux Analysables avec WinDbg sous Windows (version x64 pour les dumps x64, version x64 pour les dumps Arm64, version x86 pour les dumps x86)14 Pris en charge (utiliser l’outil correspondant à la bitness de la même plateforme)14
Dumps macOS Non pris en charge (la prise en charge des dumps Linux de WinDbg n’inclut pas macOS) Pris en charge (.NET 5 et ultérieur)4
Légèreté de la mise en place Installeur ou winget Une commande dotnet global tool
Intégration dans un CI multiplateforme Demande des efforts Plus simple

En pratique, la ligne de partage est la suivante : WinDbg si « COM, P/Invoke ou une DLL native peuvent être en cause », dotnet-dump analyze pour « une enquête de fuite mémoire purement en code managé, que l’on veut aussi pouvoir exécuter en CI ou sur plusieurs plateformes ». Les deux outils partageant le même ensemble de commandes SOS, ce qui a été appris avec l’un s’applique presque directement à l’autre. Notez que pour traiter un dump collecté sur macOS, WinDbg n’est pas une option : dotnet-dump (ou LLDB) est alors le seul choix possible.

8. Sans symboles lisibles, rien ne démarre

Une partie des procédures vues jusqu’ici fonctionne raisonnablement bien même sans symboles (PDB) correctement chargés. Comme indiqué au chapitre 4, !clrstack, !dumpheap -stat et !gcroot lisent directement les métadonnées du CLR et les données du tas, si bien que les frames et les informations de type s’affichent même sans PDB. Ce qui est perdu en l’absence de PDB, ce sont les noms de fichiers source et les numéros de ligne du code managé, ainsi que les noms de symboles des frames et modules natifs (seules des adresses s’affichent à la place des noms de fonction). Dans une situation où vous n’avez que le dump et l’exécutable, et où vous voulez d’abord simplement comprendre ce qui s’est passé, il est parfaitement acceptable de commencer par !threads!clrstack avant même de vous lancer dans la recherche de PDB. Cela dit, si vous voulez remonter jusqu’à la ligne source pour identifier précisément la cause, c’est une autre affaire. Au chapitre 2, nous avons ajouté le chemin de vos propres PDB via .sympath+, mais en pratique, le simple fait de « ne pas savoir où se trouve le PDB correspondant à l’EXE/DLL distribué » bloque souvent l’enquête avant qu’elle n’atteigne la ligne source — plus fréquemment encore que ne le laisse penser l’article de collecte.

Ce que contient réellement un PDB (et ce qu’il ne contient pas), les Portable PDB, et Source Link (un mécanisme qui intègre des métadonnées de contrôle de code source dans un assembly, permettant au débogueur de récupérer directement le code source correspondant au commit du build) sont regroupés dans un seul article : « Qu’est-ce qu’un PDB ? ».15 Si vous intégrez l’analyse de dumps dans une pratique opérationnelle continue, conserver un PDB pour chaque build et activer Source Link est une préparation tout aussi importante que la configuration de la collecte elle-même. Négliger ce point vous prive de toute ligne source dans la sortie de !clrstack, vous laissant tâtonner avec pour seuls indices des adresses et des noms de type.

9. Étude de cas — analyse de dump dans une enquête sur une fuite de handles

Un article précédent, « Enquête sur un plantage après longue durée de fonctionnement d’une caméra industrielle — le cas de la fuite de handles », portait sur une application de pilotage de caméra industrielle qui plantait soudainement après de longues heures de fonctionnement, où le coupable s’est révélé être une fuite de handles plutôt qu’une fuite de mémoire. Dans ce type d’enquête, un dump est efficace lorsque la combinaison suivante se présente :

  1. Confirmer avec !dumpheap -stat que le tas managé est sain (le nombre d’instances et la taille par type ne croissent pas sans limite)
  2. Si, malgré cela, seul le nombre de handles du processus continue d’augmenter, on peut en conclure que ce qui fuit n’est pas des objets managés mais des handles OS (fichiers, événements, handles alloués en interne par le SDK de la caméra, etc.)
  3. Si un objet wrapper managé possédant un SafeHandle subsiste, retracer sa racine GC avec !gcroot pour identifier l’endroit où une référence persiste alors qu’elle aurait dû être libérée

Autrement dit, !dumpheap -stat sert de point de bascule pour déterminer s’il s’agit ou non d’une croissance du tas managé ; une fois cela écarté, le centre de gravité de l’enquête se déplace vers un outil de détection d’anomalies aux frontières natives comme Application Verifier. La façon de construire ce type de socle de test des cas anormaux est traitée dans « Construire un socle de test des cas anormaux Windows avec Application Verifier ». L’analyse de dump traite « l’état actuel des choses », tandis qu’Application Verifier traite « la reproduction anticipée d’une anomalie » : combiner les deux est la pratique de référence pour l’investigation des défaillances liées à un fonctionnement prolongé.

10. Résumé

Lire un dump de plantage demande plus de temps à maîtriser que de le collecter, mais les schémas types ne sont pas si nombreux.

  1. Installer WinDbg et pointer le chemin des symboles à la fois vers le serveur de symboles public de Microsoft et vers vos propres PDB (chapitre 2)
  2. Pour une application .NET, charger l’extension SOS (.loadby sos clr / .loadby sos coreclr, ou chargement automatique ; chapitre 3)
  3. Commencer par !clrstack!pe en cas d’exception, !dumpheap -stat!gcroot en cas d’augmentation de mémoire, et !analyze -v pour un plantage natif (chapitres 4 à 6)
  4. Si l’usage est une enquête purement managée, envisager aussi le plus léger dotnet-dump analyze (chapitre 7)

Et ce qui sert de fondation à tout cela, c’est la gestion des PDB et des symboles. Décider, au moment même où vous mettez en place la configuration de collecte des dumps, de conserver un PDB pour chaque build et d’activer Source Link change considérablement le temps d’enquête le jour où un incident survient réellement. Si l’analyse en interne est difficile ou que vous manquez de temps, n’hésitez pas à nous envoyer l’ensemble des dumps et des logs : nous pouvons nous en charger.

Articles connexes

Domaines de conseil associés

KomuraSoft LLC prend en charge la recherche des causes de dysfonctionnements combinant dumps de plantage et logs, l’isolement des défaillances qui n’apparaissent qu’après un fonctionnement prolongé, ainsi que le conseil sur la conception du dispositif même de conservation et d’analyse des dumps et des PDB.

Références

  1. Microsoft Learn, Install the Windows debugger. Sur l’installation de WinDbg via winget ou le Microsoft Store, les versions d’OS prises en charge (Windows 10 1607 et ultérieur, Windows 11) et les architectures (x64, ARM64), ainsi que le comportement de mise à jour automatique.  2 3

  2. Microsoft Learn, Symbol path for Windows debuggers. Sur la configuration du chemin des symboles via la variable d’environnement _NT_SYMBOL_PATH, et la définition d’un chemin par défaut vers le serveur de symboles public avec la commande .symfix 2

  3. Microsoft Learn, SOS debugging extension. Sur la façon dont l’extension SOS permet de collecter des informations sur le tas managé, de détecter la corruption du tas et d’afficher les types de données internes au runtime, et sur le fait que la syntaxe dans WinDbg est ![commande] 2

  4. Microsoft Learn, Dump collection and analysis utility (dotnet-dump). Sur le fait que dotnet-dump analyze fournit une session interactive où les commandes SOS fonctionnent directement, qu’il ne peut pas afficher les frames de pile natifs car ce n’est pas un débogueur natif, et que la prise en charge de macOS nécessite .NET 5 ou ultérieur.  2 3 4

  5. Microsoft Learn, Microsoft public symbol server. Sur la syntaxe du chemin de symboles srv*DownstreamStore*https://msdl.microsoft.com/download/symbols, et sa configuration avec un cache local via .symfix

  6. Microsoft Learn, Debugging Managed Code Using the Windows Debugger. Sur le fait que le runtime .NET Framework est clr.dll et celui de .NET Core/.NET 5+ est coreclr.dll, le chargement d’extensions depuis un répertoire voisin via .loadby, et le chargement automatique dans WinDbg à partir de la version 10.0.18317.1001.  2

  7. Microsoft Learn, SOS installer (dotnet-sos). Sur l’installation locale de l’extension SOS via dotnet-sos install, et la commande de chargement manuel nécessaire avec les anciennes versions du débogueur. 

  8. Microsoft Learn, SOS debugging extension - Commands. Sur le fait que la commande Threads (alias clrthreads dans les environnements lldb) liste l’ID, le domaine, la dernière exception levée, etc. de chaque thread. 

  9. Microsoft Learn, SOS debugging extension - Commands. Sur le fait que la commande CLRStack affiche une pile d’appels du code managé uniquement, que l’option -a affiche à la fois les variables locales et les arguments, et que les symboles (SYMOPT_LOAD_LINES) n’affectent que l’affichage des noms de fichiers source et des numéros de ligne, pas l’affichage des frames eux-mêmes.  2

  10. Microsoft Learn, SOS debugging extension - Commands. Sur le fait que la commande PrintException (pe) affiche la dernière exception levée sur le thread courant lorsqu’aucune adresse n’est indiquée, et que -nested permet aussi d’afficher les exceptions imbriquées. 

  11. Microsoft Learn, Debug a memory leak in .NET et Dump collection and analysis utility (dotnet-dump) - Analyze memory leaks and allocations. Sur l’affichage statistique du nombre d’instances et de la taille totale par type par dumpheap -stat, et sur la façon de poursuivre l’enquête à partir de là.  2

  12. Microsoft Learn, SOS debugging extension - Commands. Sur le fait que la commande GCRoot recherche dans l’ensemble du tas managé et de la table des handles, et recense les références (racines) vers l’objet indiqué. 

  13. Microsoft Learn, Using the !analyze Extension et !analyze (WinDbg). Sur l’analyse automatique du plantage/de l’exception via !analyze -v, la signification des champs de sortie tels que FAULTING_IP et MODULE_NAME, et !analyze -hang pour les enquêtes sur les hangs. 

  14. Microsoft Learn, Debug Linux dumps. Sur le fait que les dumps Linux peuvent être analysés sous Windows avec WinDbg ou dotnet-dump, et qu’il faut utiliser une version de l’outil correspondant à la bitness (x64/Arm64/x86) de l’environnement de collecte.  2

Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.

Ces pages replacent le sujet dans un contexte plus large de services et de décisions.

Cet article est directement lié aux services suivants.

Questions fréquentes

Questions souvent posées lors d’une consultation sur le sujet de cet article.

Par quelle commande commencer la lecture d'un dump de plantage d'application .NET ?
Il existe trois types d'enquête. Si l'application s'est arrêtée sur une exception non gérée, identifiez avec !threads le thread porteur de l'exception, affichez la pile managée avec !clrstack, puis vérifiez avec !pe le type, le message et les exceptions internes de l'objet exception. Pour une enquête sur une mémoire qui augmente continuellement, identifiez avec !dumpheap -stat le type dominant en volume, puis passez en revue avec !gcroot les racines (champs statiques, abonnements à des gestionnaires d'événements) qui retiennent cet objet. Pour un plantage natif, commencez par l'analyse automatique de !analyze -v.
Comment charger l'extension SOS dans WinDbg ?
Pour .NET Framework, utilisez .loadby sos clr ; pour .NET Core/.NET 5+, .loadby sos coreclr. À partir de la version 10.0.18317.1001, WinDbg charge automatiquement SOS dès qu'il détecte que le processus cible a chargé coreclr.dll. Dans les environnements où le chargement automatique ne fonctionne pas, vous pouvez l'installer localement avec l'outil dotnet-sos et le charger manuellement avec .load. Pour vérifier que le chargement a réussi, contrôlez que !sos.help ou !Threads renvoie une réponse sans erreur.
Peut-on analyser un dump sans PDB (symboles) ?
Dans une certaine mesure, oui. !clrstack, !dumpheap -stat et !gcroot lisent directement les métadonnées du CLR et les données du tas, si bien que les frames et les informations de type s'affichent même sans PDB. Ce qui est perdu, ce sont les noms de fichiers source et les numéros de ligne du code managé, ainsi que les noms de symboles des frames natifs. Pour remonter jusqu'à la ligne source et identifier précisément la cause, il faut faire pointer le chemin des symboles à la fois vers le serveur de symboles public de Microsoft et vers l'emplacement de vos propres PDB. La conservation des PDB à chaque build et l'activation de Source Link sont des points essentiels sur le plan opérationnel.
Comment choisir entre dotnet-dump analyze et WinDbg ?
Utilisez WinDbg si COM, P/Invoke ou des DLL natives sont susceptibles d'être en cause, et dotnet-dump analyze pour une enquête portant purement sur du code managé. dotnet-dump s'installe avec une seule commande dotnet global tool et permet d'utiliser directement la plupart des commandes SOS comme clrstack ou dumpheap, mais il ne gère pas les frames de pile natifs et !analyze -v n'y est pas disponible. Un dump collecté sur macOS ne peut pas être analysé avec WinDbg : dotnet-dump (ou LLDB) est alors le seul choix possible. Les deux outils partageant le même ensemble de commandes SOS, ce que vous apprenez avec l'un s'applique presque directement à l'autre.

Profil de l’auteur

Page de présentation de l’auteur de l’article.

Go Komura

Représentant de KomuraSoft LLC

Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.

Retour au blog