Débogage de la mémoire sous Linux : outils et techniques clés

Dernière mise à jour: 26 de Février 2026
  • Linux propose des commandes telles que free, vmstat, ps et top pour examiner l'utilisation réelle de la mémoire et du processeur, en faisant la distinction entre la mémoire utilisée, la mémoire libre et la mémoire en cache.
  • Des outils comme GDB et Valgrind permettent de détecter les erreurs de segmentation, les fuites de mémoire, les accès illégaux et les variables non initialisées dans les programmes natifs.
  • Dans les environnements .NET Core, la combinaison de dotnet-dump, LLDB et SOS facilite l'analyse approfondie des vidages mémoire sous Linux et Windows.
  • Un flux de travail de diagnostic structuré, combinant les métriques système, les journaux et l'analyse des vidages mémoire, réduit considérablement le temps nécessaire pour localiser et corriger les problèmes de mémoire.

Débogage de la mémoire sous Linux

Lorsqu'un problème survient sur un serveur Linux, la cause réside souvent dans l' utilisation de la mémoire et les outils de débogage . Cependant, tant que vous ne savez pas quoi chercher, tout semble un véritable chaos de chiffres et de processus. Comprendre ce qui se passe dans la RAM, le comportement de vos programmes et comment capturer des vidages mémoire est essentiel pour éviter de procéder à un dépannage à l'aveugle à chaque apparition d'une erreur étrange ou d' une erreur de segmentation.

Dans cet article, nous examinerons en détail et de manière simple comment inspecter la mémoire, déboguer des programmes et analyser les vidages mémoire sous Linux à l'aide des commandes système (free, vmstat, /proc/meminfo), de débogueurs comme GDB, d'analyseurs de mémoire comme Valgrind et d'utilitaires spécifiques à .NET et à d'autres environnements. L'objectif est de vous fournir un ensemble d'outils pratiques pour diagnostiquer les problèmes de mémoire et de processeur sur les serveurs et dans les environnements de développement professionnels.

Aperçu : La mémoire sous Linux et pourquoi il ne faut pas viser les 100 %

Sur un serveur Linux, la RAM sert de mémoire vive pour stocker rapidement les données et le code que le système devra réutiliser prochainement. L'accès à la RAM étant beaucoup plus rapide que l'accès au disque, le noyau exploite cette rapidité pour l'utiliser comme cache pour les fichiers, les tampons et les pages mémoire susceptibles d'être réutilisés sous peu.

Dans le contexte d'un serveur web Apache ou Nginx , ou d'un serveur de base de données comme MySQL ou MariaDB, il est essentiel de connaître la quantité de mémoire utilisée, disponible et mise en cache pour dimensionner correctement les services et comprendre les espaces de noms et les cgroups . D'ailleurs, des outils d'optimisation comme MySQLTuner utilisent ces données (et d'autres informations) pour suggérer des paramètres de mémoire tampon, de cache et de connexion.

Il est important de comprendre un concept qui surprend souvent au premier abord : la RAM est conçue pour être utilisée . Un taux d'utilisation de 90 % voire 100 % n'est pas forcément problématique ; Linux utilise le cache disque pour optimiser le système. Ce qui est réellement préoccupant, ce sont les erreurs de mémoire insuffisante , les plantages de processus avec un message OOM (Out Of Memory) ou le blocage de services, et non une simple indication de « forte utilisation » sur le graphique.

Il n'est judicieux de passer à une optimisation agressive que si vous constatez que le serveur devient instable, lent ou interrompt les services en raison d'une utilisation excessive de la mémoire, ou si vous savez que des pics de trafic sont à venir et pourraient saturer les ressources actuelles.

Commandes de base pour inspecter la mémoire sous Linux

Outils de gestion de la mémoire sous Linux

La première étape pour résoudre les problèmes de mémoire consiste à comprendre la quantité totale de RAM disponible et sa répartition entre mémoire utilisée, mémoire libre, cache et espace d'échange. Linux propose plusieurs utilitaires à cet effet, chacun offrant un niveau de détail différent.

commande libre : aperçu rapide de la RAM et de l’espace d’échange

La commande la plus couramment utilisée pour un aperçu rapide est gratuite, notamment avec le paramètre -h Pour afficher les tailles dans un format lisible : Pour plus d’informations sur l’interprétation et l’optimisation de ces indicateurs, consultez optimiser les statistiques de mémoire.

free -h

Le résultat typique affiche, en quelques lignes, la mémoire totale, utilisée, libre, partagée, tampon et cache , pour la RAM et l'espace d'échange. Vous verrez quelque chose comme ceci :

Mémoire totale utilisée, libre, partagée, en cache : 2.0 Go, 1.5 Go, 470 Mo, 300 Mo, 0 o, 414 Mo ; tampons/cache : 1.1 Go, 885 Mo ; swap : 0 o, 0 o, 0 o

ligne -/+ buffers/cache C'est particulièrement utile car cela indique la mémoire réellement utilisée par les processus (hors tampons/cache) et la mémoire potentiellement disponible pour les nouvelles applications. Beaucoup de personnes voient peu de « mémoire libre » sur la première ligne et s'inquiètent, alors qu'en réalité, une grande partie est simplement mise en cache et peut être utilisée. réutilisé sans problème.

vmstat : métriques de la mémoire active et inactive, et du système

Lorsque vous avez besoin d'informations plus détaillées, vmstat fournit une vue plus technique du système. Avec :

vmstat -s -S M

Vous obtiendrez une liste indiquant la mémoire totale, la mémoire utilisée, la mémoire libre, la mémoire active, la mémoire inactive, les tampons, la mémoire d'échange, etc. Par exemple :

Mémoire totale : 2048 Mo ; mémoire utilisée : 1582 Mo ; mémoire active : 1124 Mo ; mémoire inactive : 406 Mo ; mémoire libre : 465 Mo ; mémoire tampon : 0 Mo ; cache d’échange : 407 Mo ; espace d’échange total : 0 Mo ; espace d’échange utilisé : 0 Mo ; espace d’échange libre : 0 Mo

Le concept de mémoire inactive est intéressant : il s’agit de mémoire considérée comme utilisée mais non associée à des processus actifs. De ce fait, elle se comporte comme de la mémoire que le système peut récupérer . Cela explique pourquoi Linux peut sembler « utiliser tout l’espace », alors qu’en réalité, il dispose de mémoire libre en cas de besoin.

/proc/meminfo : les détails bruts du noyau

Si vous souhaitez connaître tous les détails gérés par le noyau, vous pouvez toujours consulter le fichier /proc/meminfo :

cat /proc/meminfo

Ce fichier comprend des dizaines de champs relatifs à la gestion de la mémoire interne : mémoire totale, mémoire libre, tampons, cache, slab, hugepages, mémoire disponible, etc. Il est très utile pour les outils automatisés et les scripts de surveillance, bien que sa lecture directe soit un peu moins conviviale que celle des commandes `free` ou `vmstat` et nécessite une compréhension approfondie de la signification de chaque champ.

Panneaux de contrôle et leur « réalité parallèle »

Si vous gérez un serveur avec des panneaux de contrôle comme cPanel, Plesk, VestaCP ou Webmin , vous constaterez qu'ils affichent généralement des graphiques de la mémoire utilisée, libre et en cache via une interface web. Ces données sont pratiques, mais n'oubliez pas qu'elles sont mises à jour périodiquement et ne reflètent pas toujours l'état en temps réel. Pour un diagnostic approfondi et un réglage précis, il est toujours préférable d'utiliser le terminal et ses commandes natives.

Débogage des processus et de la mémoire avec les outils système

Une fois que vous connaissez la quantité de mémoire disponible et son utilisation générale, l'étape suivante consiste à identifier les processus qui consomment anormalement des ressources et à analyser leur comportement. C'est là qu'interviennent les utilitaires classiques tels que ps, top, htop, strace et ltrace, ainsi que les commandes réseau et disque permettant d'éliminer les goulots d'étranglement.

ps, top et htop : une radiographie des processus et du processeur

La commande `ps` affiche les processus actifs. Combinée à des filtres et au tri, elle permet de localiser rapidement ce qui consomme le processeur.

ps aux --sort=-%cpu | head

Ceci affiche les processus triés par pourcentage d'utilisation du processeur , ainsi que l'utilisation de la mémoire, l'utilisateur et la commande. C'est idéal pour identifier rapidement le processus principal lorsque le serveur manque de ressources ; la maîtrise du terminal permet d'agir vite.

  Guide complet de Voiceflow : la révolution dans la conception d’agents conversationnels

En revanche, `top` et sa variante plus visuelle `htop` offrent une vue en temps réel des processus, de l'utilisation du processeur, de l'utilisation de la mémoire, de l'état (R, S, D, etc.) et de la charge moyenne . Pour lancer `top`, utilisez :

top -o %CPU

Vous pouvez vous concentrer sur les processus qui utilisent le plus le processeur. Au-delà des chiffres, il est important de rechercher des tendances.

  • Processus en état R (en cours d'exécution) qui restent longtemps bloqués au sommet.
  • Changements soudains de la charge moyenne qui indiquent des pics de charge récents.
  • allocation du processeur dans %us, %sy et %wa (temps utilisateur, temps système et attente d'E/S).
  • Si le processus problématique est un service système, un utilisateur spécifique ou un démon.
  • Si la consommation est stable ou Ça monte et ça descend par à-coups., ce qui peut indiquer des tâches par lots ou un trafic irrégulier.

Une valeur %wa (attente d'E/S) très élevée est un indice que le goulot d'étranglement ne se situe peut-être pas dans le processeur, mais dans le disque ou le sous-système de stockage.

Examen des discussions en cours : top -H

Pour les applications multithread (Java, Python, Node, etc.), il ne suffit pas de savoir quel processus consomme du CPU ; il faut identifier le thread précis qui s’exécute de manière incontrôlée . Avec :

top -H -p PID

Vous obtenez les détails de chaque thread du processus. Si l'un d'eux affiche 100 % d'utilisation et que les autres sont inactifs, il y a probablement une boucle infinie, un problème de blocage inhabituel ou une section critique mal conçue dans cette partie du code.

Priorité du processus : nice et renice

Si un processus gourmand en ressources est légitime mais que vous souhaitez éviter qu'il ne surcharge le reste du système, vous pouvez ajuster sa priorité (ou son niveau de priorité) . Les commandes `nice` et `renice` permettent de démarrer des processus avec une priorité plus faible ou d'ajuster la priorité d'un processus existant, afin que le noyau leur alloue moins de temps CPU par rapport aux autres tâches critiques.

Autres commandes clés : pidof, kill, strace et ltrace

Lorsque le système est soumis à des pressions, il est utile de pouvoir localiser et contrôler rapidement les processus :

  • pidof: récupère l'identifiant du processus (PID) à partir de son nom, idéal pour les scripts ou les interventions rapides.
  • tuer: envoie des signaux aux processus (TERM, KILL, etc.), soit pour les arrêter de manière ordonnée, soit pour interrompre la tâche s'ils sont bloqués.
  • strass: montre le appels système qui exécute un processus ; idéal pour voir sur quoi il est bloqué (lectures de disque, sockets, etc.).
  • traceSimilaire à strace, mais axé sur appels aux librairies, utile pour déboguer les problèmes d'utilisation d'API partagées.

Ces outils ne sont pas seulement utiles pour la recherche de fuites de mémoire ou de plantages, ils sont également largement utilisés en cybersécurité, en analyse forensique et en débogage de comportements binaires étranges.

Commandes pour les fichiers et les disques : lsof, df, du, locate

Lorsque vous soupçonnez un problème avec le stockage (par exemple, de nombreux fichiers ouverts ou des disques pleins), d'autres commandes entrent en jeu :

  • lsof: listez les fichiers ouverts par un processus, utile pour détecter les fuites de descripteurs ou de fichiers qui empêchent le démontage d'un système de fichiers.
  • df: montre le Espace disque libre par système de fichiers, essentiel pour exclure 100 % des disques à l'origine de pannes en cascade.
  • du: calcule le espace utilisé par les répertoires, très utile pour localiser les dossiers qui grossissent de manière incontrôlable (journaux, sauvegardes, etc.).
  • localiser: permet de rechercher un fichier par son nom à l'aide d'une base de données indexée, plus rapidement que la fonction de recherche dans de nombreuses situations.

Commandes réseau pour le diagnostic : nc, netstat, ab, tcpdump, wireshark, nmap

Souvent, les problèmes de performance et de mémoire s'accompagnent de goulots d'étranglement ou d'attaques sur le réseau ; il est donc judicieux de disposer de quelques outils de base :

  • nc (netcat): un véritable couteau suisse des réseaux ; ouvre des sockets, envoie et reçoit des données, permet les tests de service, voire même des tunnels improvisés.
  • netstat: affiche les connexions actives, les sockets d'écoute et les statistiques réseau, utile pour voir s'il y a beaucoup de connexions vers un port particulier.
  • ab (Apache Benchmark): génère une charge sur un serveur web afin de mesurer les temps de réponse et le comportement en situation de stress.
  • tcpdump et WiresharkIls capturent les paquets réseau pour analyser le trafic en profondeur; tcpdump en console, Wireshark avec interface graphique.
  • nmapScanner de ports et de services, largement utilisé pour les audits de sécurité et la vérification des surface d'exposition du serveur.

GDB : le débogueur classique pour les erreurs de mémoire et les plantages d'exécution

Lorsqu'un programme Linux plante suite à une erreur de segmentation ou à une autre erreur majeure, l'étape suivante consiste à utiliser un bon débogueur. L'outil phare de l'écosystème GNU est GDB (GNU Debugger) , qui permet d'inspecter l'état interne d'un programme, de l'interrompre à tout moment, de visualiser les variables et l'utilisation de la mémoire, et de suivre son exécution pas à pas.

GDB a été initialement conçu pour les programmes C et C++, mais il a été étendu à d'autres langages tels que Rust et même l'assembleur , ainsi qu'à la gestion des chemins de bibliothèques comme LD_LIBRARY_PATH . Il est fondamental en développement, mais aussi en cybersécurité, où il est utilisé pour la rétro-ingénierie, la recherche de vulnérabilités et le développement ou le débogage d'exploits.

Démarrez GDB et exécutez un programme

Pour utiliser GDB avec un exécutable, il est recommandé de compiler le programme avec informations de débogage en utilisant l'option -g du CCG :

gcc -g -Wall programa.c -o programa

Ensuite, vous le lancez avec :

gdb programa

Dans GDB, le programme n'est pas encore en cours d'exécution. Vous pouvez le démarrer avec :

  • courirDémarrez le programme avec les arguments de votre choix.
  • Commencer: identique à run, mais s'arrête au début de la fonction main.

Si vous avez un exécutable appelé, par exemple, suma Et si vous voulez voir comment il traite ses arguments, vous devez utiliser GDB. run 3 5 pour le lancer avec ces paramètres depuis le débogueur.

Points d'arrêt et points de surveillance : interrompre le programme là où c'est nécessaire

Les points d'arrêt sont des points de suspension dans le code source : lorsque l'exécution les atteint, le programme se met en pause et vous pouvez examiner son état interne. Dans GDB, ils sont définis avec la commande :

break lugar

où « emplacement » peut être un nom de fonction, un numéro de ligne ou un chemin fichier:ligne . Voici un exemple typique :

break main

Ainsi, GDB s'arrête dès l'entrée dans la fonction principale. Lorsque le programme s'arrête à un point d'arrêt, vous pouvez consulter le code avec la commande `l` (liste), vérifier les variables et parcourir la pile d'appels.

Les points d'observation fonctionnent différemment : au lieu de s'arrêter à un point précis du code, ils s'arrêtent lorsque la valeur d'une variable change . Ils sont très utiles pour détecter les corruptions de mémoire ou les modifications inattendues de structures critiques sans avoir à inonder le code d'instructions d'affichage.

Contrôle précis du débit : étape, suivant, continuer, terminer

Une fois le programme arrêté à un point d'arrêt, plusieurs options s'offrent à vous :

  • étape: exécute la ligne suivante et entre dans les fonctions appelées.
  • next: exécute la ligne suivante sans entrer dans les fonctions (les exécute « toutes en même temps »).
  • continuer: reprend l'exécution jusqu'au prochain point d'arrêt ou jusqu'à la fin du programme.
  • finition: continue jusqu'à ce que la fonction actuelle se termine et revient au point d'où elle a été appelée.
  Guide complet des plateformes de conception visuelle pour les agents conversationnels et l'IA générative

Cela vous permet d'inspecter le code suspect étape par étape, sans avoir à « avaler » l'intégralité du programme. Une astuce pratique : dans GDB, Appuyer sur Entrée répète la dernière commandeidéal pour réaliser de nombreux next o step suivi d'une réduction de la saisie.

Pile d'appels et cadres : voyez comment nous en sommes arrivés là

Pour comprendre pourquoi une erreur s'est produite à un moment précis, il est essentiel d'examiner les fonctions appelées jusqu'à ce moment. La structure qui stocke ces informations est la pile d'appels . GDB propose plusieurs commandes pour la gérer :

  • bt (backtrace) : affiche la pile complète, avec la liste des fonctions imbriquées et les numéros de trame.
  • up: remonte d'un niveau dans la pile, jusqu'au point qui a appelé la fonction actuelle.
  • down: descend d'un niveau, à la fonction qui était en cours d'exécution.
  • fr (frame) : affiche la frame actuelle ou vous permet de passer à une autre en indiquant son numéro.

Cela vous permet de vous positionner à différents niveaux de l'appel (par exemple, en passant d'une fonction interne à la fonction principale ) et de voir comment les variables se trouvaient à chaque endroit.

Interaction avec la mémoire : définir, retourner, trace d'exécution yx

L'un des principaux avantages de GDB est qu'il permet de lire et de modifier la mémoire même lorsque le programme est arrêté. Voici quelques opérations utiles :

  • set: modifie la valeur d'une variable pendant l'exécution, idéal pour tester des scénarios sans recompilation.
  • valeur de retour: force la fonction actuelle à renvoyer la valeur spécifiée, sans poursuivre l'exécution de son code.
  • retour en arrière: déjà vu, pour afficher la pile d'appels actuelle.
  • x: examine le contenu de la mémoire à partir d'une adresse, avec différents formats et tailles (par exemple, x/4xw 0x7fffffffe000 (pour voir quatre mots en hexadécimal).

Grâce à ces options, vous pouvez reproduire des erreurs, vérifier si une entrée dangereuse provoque un dépassement de capacité ou inspecter des structures de données complexes sur la pile ou le tas.

Débogage post-mortem avec vidages de mémoire

Linux peut générer un fichier core lorsqu'un processus plante suite à un signal tel que SIGSEGV. Ce fichier contient l'état complet du processus au moment du plantage : mémoire, registres, pile, etc. Pour l'activer dans une session, il suffit de :

ulimit -c unlimited

Pour les activer de manière plus permanente pour les utilisateurs, vous pouvez modifier le fichier /etc/security/limits.conf et ajouter une ligne comme celle-ci :

* soft core unlimited

Lorsqu'un programme plante, il génère un fichier généralement nommé « core » dans le répertoire de travail. Vous pouvez ensuite l'analyser avec GDB comme ceci :

gdb ejecutable core

Cela vous permet d'effectuer une analyse post-mortem presque comme si le programme était encore en fonctionnement, idéal lorsque la panne n'est pas facilement reproductible à la demande.

Valgrind : recherche des fuites de mémoire et des erreurs

Pour de nombreux problèmes de mémoire en C/C++ (et langages similaires), GDB est insuffisant car il n'est pas conçu pour détecter automatiquement les lectures illégales, les fuites de mémoire ou l'utilisation de mémoire non initialisée . C'est là qu'intervient Valgrind : un système de débogage et de profilage qui émule le processeur et surveille chaque accès mémoire.

Valgrind inclut plusieurs outils, mais le plus utilisé est Memcheck , qui remplace le gestionnaire de mémoire standard de C par le sien, doté de zones de protection autour des blocs alloués . Cela lui permet de détecter :

  • Utilisation de la mémoire non initialisée (variables utilisées avant de se voir attribuer une valeur).
  • Lectures/écrits après avoir fait du bénévolat (utiliser après libération).
  • Accès hors des limites d'un bloc de mémoire.
  • Fuites de mémoire (malloc sans libération, pointeurs perdus, etc.).

Exemple sans erreur : programme « propre » sous Memcheck

Supposons que vous compiliez un petit programme « hello world » avec des informations de débogage :

gcc -Wall -gstabs valgrind_hello_good.c -o valgrind_hello_good

Si vous l'exécutez sous Valgrind avec :

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_good

Vous obtiendrez une trace où, à la fin, le RÉSUMÉ DES ERREURS indique 0 erreur et aucune fuite de mémoire n'est signalée. Ceci confirme que, du point de vue de Memcheck, le programme ne présente aucune anomalie de mémoire.

Détecter les fuites de mémoire

Si vous modifiez le code pour effectuer un malloc sans libérer la mémoire (par exemple, en réservant un octet sans jamais le libérer) et que vous recompilez :

gcc -Wall -gstabs valgrind_hello_bad.c -o valgrind_hello_bad

lors de l'exécution :

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_bad

Valgrind affichera un résumé du tas avec une valeur « en cours d'utilisation à la sortie » non nulle, indiquant la quantité de mémoire non libérée. De plus, la section « perte certaine » indiquera le nombre d'octets et de blocs ayant fui, ainsi que la trace d'appel à l'origine de la fuite (fonction, fichier et ligne de code).

Dans les cas plus complexes, où des filtres sont utilisés, par exemple, 100 octets dans une fonction leak()La sortie de Valgrind vous indiquera clairement où se trouve le malloc problématique, permettant l'ajout du free et vérifier ensuite que le résumé revient à zéro fuite.

Actes illégaux et accès hors de portée

Une autre erreur courante détectée par Memcheck est l'écriture à des adresses invalides , par exemple, l'écriture à l'adresse mémoire 0 (NULL) ou au-delà de la fin d'un tableau. Si vous compilez un programme qui effectue une écriture illégale :

gcc -gstabs -Wall valgrind_illegal_read_write.c -o valgrind_illegal_read_write

et vous l'exécutez avec:

valgrind -v ./valgrind_illegal_read_write

Vous verrez des messages comme :

Écriture invalide de taille 4 à l'adresse 0x80483C4 : main (valgrind_illegal_read_write.c:8) L'adresse 0x0 n'est ni empilée, ni allouée par malloc, ni libérée (récemment).

Cela vous indique précisément où l'écriture illégale a eu lieu et quelle était son ampleur, chose qui, dans les exécutions normales, se manifeste généralement par une simple « erreur de segmentation » sans aucun autre indice.

Variables non initialisées et leurs dépendances de valeur

Memcheck vous alerte également lorsqu'un La décision de contrôle dépend d'une variable non initialiséeSi vous compilez un programme avec une variable locale qui n'est jamais initialisée et qui est utilisée dans un if:

gcc -gstabs -Wall valgrind_unitialized.c -o valgrind_unitialized

et vous l'exécutez avec :

valgrind -v --track-origins=yes ./valgrind_unitialized

Le résultat contiendra quelque chose comme :

Le saut ou le déplacement conditionnel dépend de valeurs non initialisées à l'adresse 0x80483F2 : main (valgrind_unitialized.c:9) Valeur non initialisée créée par une allocation de pile à l'adresse 0x80483EA : main (valgrind_unitialized.c:7)

Le paramètre –track-origins=yes permet de localiser l'endroit où la variable non initialisée a été créée pour la première fois, ce qui accélère considérablement la correction du code.

Utilisation abusive de la mémoire libre et détection d'erreurs dans le tas

Valgrind vérifie également que La fonction free n'est appelée que sur des pointeurs valides.Si vous essayez de libérer de la mémoire qui ne provient pas de mallocOu si vous double-cliquez sur le même bloc, vous obtiendrez des messages comme celui-ci :

Appels free() / delete / delete[] / realloc() invalides à l'adresse 0x402B06C : libération (...) par 0x8048449 : main (valgrind_illegal_free.c:11)

Dans de nombreux cas, il vous indique même l'adresse d'où vous appelez. free Il est situé immédiatement après un bloc qui a déjà été libéré, permettant l'identification erreurs de calcul du pointeur ou doubles relâchements.

  Sécurité avancée sous Linux : un guide complet pour la protection des systèmes et des serveurs

En résumé, Valgrind est un outil essentiel lorsque vous soupçonnez des fuites de mémoire, des utilisations après libération ou une corruption de mémoire dans les programmes natifs, et son utilisation combinée avec GDB offre une vue très puissante de l'état interne des applications.

vidages de mémoire et analyse sous Linux et Windows

Dans les applications modernes, notamment sous .NET Core , l'analyse des problèmes complexes de mémoire ou de performances implique souvent la capture de vidages mémoire pour une analyse approfondie sur une autre machine. Ces vidages figent l'état du processus à un instant précis, à l'instar des vidages de mémoire traditionnels.

Analyse des fichiers de vidage .NET sous Linux avec dotnet-dump et LLDB

Dans les environnements .NET Core sous Linux, dotnet-dump est l'un des outils recommandés . Après avoir capturé un dump, vous pouvez commencer l'analyse avec :

dotnet-dump analyze <dump-file>

Il est important que l'analyse soit effectuée sur une machine présentant la même architecture et la même distribution Linux que l'environnement où le fichier de vidage a été généré. dotnet-dump est conçu pour le code .NET managé ; pour analyser également le code natif (C/C++), il est plus approprié d'utiliser LLDB avec l' extension SOS.

LLDB permet de déboguer le code managé et le code natif. Grâce à dotnet-sos, vous pouvez installer l'extension SOS, qui fournit des commandes spécifiques pour .NET. Pour charger correctement un dump .NET Core, LLDB et SOS nécessitent certains binaires de l'environnement où le dump a été créé :

  1. libmscordaccore.so
  2. libcoreclr.so
  3. dotnet (l'hôte utilisé pour démarrer l'application)

Ces fichiers binaires peuvent généralement être téléchargés à l'aide de l' outil dotnet-symbol . S'il s'agit d'une version privée ou s'ils ne sont pas présents sur le serveur de symboles, vous pouvez toujours les copier depuis la machine d'origine. Si les fichiers binaires ne sont pas inclus dans le fichier de sauvegarde, vous pouvez utiliser la commande suivante dans LLDB/SOS :

  • setclrpath <ruta> pour indiquer où se trouvent les fichiers binaires .NET Core.
  • setsymbolserver -directory <ruta> pour préciser l'emplacement des symboles.

Une fois que vous avez tout ce dont vous avez besoin, chargez le fichier de vidage dans LLDB en spécifiant l'hôte dotnet comme exécutable à déboguer :

lldb --core <dump-file> <host-program>

Ici C'est la route qui mène à la décharge et Il est généralement binaire. dotnet, sauf s'il s'agit d'une application autonome, auquel cas il s'agirait du fichier exécutable propre à l'application (sans l'extension .dll).

Au sein de LLDB, il est souvent nécessaire de configurer le serveur de symboles approprié avec setsymbolserver -ms utiliser le serveur Microsoft, ou setsymbolserver -directory <ruta> pour un répertoire local, et exécutez loadsymbols pour charger les symboles natifs. À partir de là, vous pouvez utiliser les commandes SOS habituelles pour analyser le tas géré, les threads, les exceptions, etc.

Analyse de fichiers Linux depuis Windows

Les fichiers de vidage générés sous Linux peuvent être analysés non seulement sur le même système, mais aussi depuis Windows avec des outils comme Visual Studio, WinDbg ou dotnet-dump. Leurs fonctionnalités varient :

  • Visual Studio: permet de nettoyer les décharges avec un mélange de code natif et managéavec une interface graphique très conviviale. Il est recommandé de consulter le guide spécifique pour Débogage des vidages mémoire de Visual Studio.
  • WinDbgPrise en charge avancée des dumps utilisateur, y compris Vidages Linux Le flux de travail est similaire à celui de Windows. Vous devez utiliser la version x64 de WinDbg pour les dumps provenant d'environnements Linux x64 ou Arm64, et la version x86 pour les dumps x86.
  • dotnet-dump Sous Windows : son utilisation est identique à celle sous Linux, avec dotnet-dump analyzeN'oubliez pas de choisir la version x64 ou x86 de l'outil en fonction de l'architecture du fichier de vidage.

Diagnostic professionnel de l'utilisation élevée du processeur et de la mémoire

Au-delà des outils spécifiques, le nettoyage de la mémoire sous Linux implique généralement une procédure structurée afin d'éviter les actions hasardeuses. Voici un schéma pratique pour les serveurs :

  • Regarder top pour détecter les schémas et processus de chargement suspects.
  • Confirmer avec ps les processus qui utilisent le plus de ressources CPU et de mémoire.
  • Vérifiez si la consommation est logique (compilations, traitement par lots, indexée) ou si elle présente un comportement anormal.
  • Analyser les fils de discussion avec top -H -p PID en ce qui concerne les processus multithread.
  • Réviser journaux de service avec journalctl ou tail.
  • Vérifiez si le problème est réellement lié au processeur ou s'il est caché dans... E/S disque utilisation d'iostat.

Pour déterminer si le goulot d'étranglement se situe au niveau du processeur ou du disque, la commande iostat -xz 1 3 est très utile : si vous constatez une utilisation élevée des disques et de longs temps d'attente, ainsi qu'un %wa élevé dans top , le problème ne vient probablement pas du processeur mais du stockage.

L'application de ce processus facilite le diagnostic de cas tels que :

  • Bots ou trafic malveillant déclenchement des processus php-fpm et surcharge du serveur web.
  • Un Microservice Java avec un thread dans une boucle infinie consommer un noyau entier.
  • Un processus Python qui semble limité par le processeur mais qui l'est en réalité verrouillé en attente du disque à chaque itération d'une boucle.

En combinant les outils système (ps, top, vmstat, free), les débogueurs (GDB, LLDB, dotnet-dump), les analyseurs de mémoire (Valgrind) et les commandes réseau et disque, vous pouvez créer une méthode de travail où les problèmes de mémoire et de performance sous Linux cessent d'être une boîte noire et deviennent quelque chose qui, avec méthode et patience, peut être identifié et corrigé avec une précision considérable.

Moniteur système avancé pour Linux
Article connexe:
Moniteur système avancé pour Linux : Guide complet