Dans Chrome 92, nous avons lancé l'inspecteur de mémoire, un outil permettant d'inspecter les tampons de mémoire linéaire. Dans cet article, nous allons voir comment nous avons amélioré l'outil d'inspection pour le débogage C/C++ et les défis techniques rencontrés en cours de route.
Voici quelques articles de blog pertinents si vous débutez avec le débogage C/C++ et l'inspecteur de mémoire :
- Vous souhaitez en savoir plus sur le débogage de la mémoire profonde ? Consultez la section Présentation de l'outil d'inspection de mémoire.
- Vous souhaitez découvrir la suite complète d'outils de débogage C/C++ ? Consultez Déboguer WASM avec des outils modernes et Déboguer WebAssembly plus rapidement.
Introduction
L'inspecteur de mémoire vous offre des options de débogage plus puissantes pour les tampons de mémoire linéaire. Dans le cas de C/C++, vous pouvez inspecter les objets de mémoire C/C++ dans la mémoire WebAssembly.
La reconnaissance des octets de votre objet parmi la mémoire WebAssembly environnante était un problème. Vous devez connaître la taille de l'objet et le nombre d'octets à partir du début de l'objet. Dans la capture d'écran ci-dessous, le premier octet d'un tableau int32
de 10 éléments est sélectionné, mais il n'est pas immédiatement clair quels autres octets appartiennent au tableau. Ne serait-il pas agréable de pouvoir reconnaître instantanément tous les octets qui appartiennent à l'objet ?
Mise en surbrillance d'un objet dans l'outil d'inspection de la mémoire
À partir de Chrome 107, l'inspecteur de mémoire met en surbrillance tous les octets d'un objet de mémoire C/C++. Cela vous aide à les distinguer de la mémoire environnante.
Regardez la vidéo ci-dessous pour découvrir le l'outil d'inspection de la mémoire en action. Lorsque vous affichez le tableau x
dans l'outil d'inspection de la mémoire, la mémoire mise en surbrillance s'affiche dans l'outil de visualisation de la mémoire, avec un nouveau chip juste au-dessus. Ce chip vous rappelle le nom et le type du souvenir en surbrillance. Cliquez sur le chip pour accéder à la mémoire de l'objet. Si vous pointez sur le chip, une croix s'affiche. Cliquez dessus pour supprimer la sélection.
Lorsque vous sélectionnez un octet en dehors de l'objet que vous inspectez, la mise en surbrillance est floutée pour éviter de vous distraire. Pour recentrer le focus, cliquez à nouveau sur l'un des octets de l'objet ou sur la puce.
La mise en surbrillance des objets ne se limite pas aux tableaux. Vous pouvez également inspecter les structures, les objets et les pointeurs. Ces modifications facilitent l'exploration de la mémoire de vos applications C/C++.
Voulez-vous essayer ? Vous devez :
- Utiliser Chrome 107 ou une version ultérieure
- Installez l'extension DWARF C/C++.
- Activez le débogage DWARF dans DevTools > Settings > Experiments > WebAssemble Debugging: Enable DWARF support (Outils de développement > Paramètres > Tests > Débogage WebAssemble : activer la compatibilité avec DWARF).
- Ouvrez cette page de démonstration.
- Suivez les instructions qui s'affichent sur la page.
Exemple de débogage
Dans cette section, nous allons examiner un bug fictif pour illustrer comment utiliser l'inspecteur de mémoire pour le débogage C/C++. Dans l'exemple de code ci-dessous, un programmeur crée un tableau d'entiers et décide d'utiliser l'arithmétique des pointeurs pour sélectionner le dernier élément. Malheureusement, le programmeur a fait une erreur dans le calcul du pointeur. Au lieu d'imprimer le dernier élément, le programme affiche des valeurs absurdes.
#include <iostream>
int main()
{
int numbers[] = {1, 2, 3, 4};
int *ptr = numbers;
int arraySize = sizeof(numbers)/sizeof(int);
int* lastNumber = ptr + arraySize; // Can you notice the bug here?
std::cout <<../ *lastNumber <<../ '\n';
return 0;
}
Le programmeur se tourne vers l'outil d'inspection de la mémoire pour déboguer le problème. Vous pouvez suivre cette démonstration. Il inspecte d'abord le tableau dans l'inspecteur de mémoire et constate que le tableau numbers
ne contient que les entiers 1
, 2
, 3
et 4
, comme prévu.
Il affiche ensuite la variable lastNumber
dans le volet Champ d'application et remarque que le pointeur pointe vers un entier en dehors du tableau. Muni de ces informations, le programmeur se rend compte qu'il a mal calculé le décalage du pointeur à la ligne 8. Il aurait dû être ptr + arraySize - 1
.
Bien qu'il s'agisse d'un exemple jouet, il illustre comment la mise en surbrillance des objets transmet efficacement la taille et la position des objets mémoire, ce qui peut vous aider à mieux comprendre ce qui se passe dans la mémoire de votre application C/C++.
Comment DevTools détermine-t-il les éléments à mettre en surbrillance ?
Dans cette section, nous allons examiner l'écosystème d'outils qui permet le débogage C/C++. Plus précisément, vous apprendrez comment les outils de développement, V8, l'extension DWARF C/C++ et Emscripten permettent d'effectuer le débogage C/C++ dans Chrome.
Pour exploiter tout le potentiel du débogage C/C++ dans les outils pour les développeurs, vous avez besoin de deux éléments:
- Extension DWARF C/C++ installée dans Chrome
- Fichiers sources C/C++ compilés en WebAssembly avec le dernier compilateur Emscripten, comme indiqué dans cet article de blog
Mais pourquoi ? V8 , le moteur JavaScript et WebAssembly de Chrome, ne sait pas exécuter C ni C++. Grâce à Emscripten, un compilateur C/C++ vers WebAssembly, vous pouvez compiler des applications intégrées en C ou C++ en tant que WebAssembly et les exécuter dans le navigateur.
Lors de la compilation, emscripten intègre des données de débogage DWARF dans votre binaire. De manière générale, ces données aident l'extension à déterminer quelles variables WebAssembly correspondent à vos variables C/C++, et plus encore. De cette façon, DevTools peut afficher vos variables C++, même si V8 exécute WebAssembly. Si vous êtes curieux, consultez cet article de blog pour obtenir un exemple de données de débogage DWARF.
Que se passe-t-il réellement lorsque vous révélez le lastNumber
? Dès que vous cliquez sur l'icône de mémoire, DevTools vérifie la variable que vous souhaitez inspecter. Il interroge ensuite l'extension sur le type de données et l'emplacement de lastNumber
. Dès que l'extension répond avec ces informations, l'inspecteur de mémoire peut afficher la tranche de mémoire appropriée et, connaissant son type, il peut également afficher la taille de l'objet.
Si vous examinez lastNumber
dans l'exemple précédent, vous remarquerez peut-être que nous avons inspecté lastNumber: int *
, mais que le chip dans l'inspecteur de mémoire indique *lastNumber: int
. Pourquoi ? L'outil d'inspection utilise le déréférencement de pointeur de style C++ pour indiquer le type d'objet qui vous est présenté. Si vous inspectez un pointeur, l'inspecteur vous indique vers quoi il pointe.
Mise en surbrillance persistante des étapes du débogueur
Lorsque vous affichez un objet dans l'outil d'inspection de la mémoire et que vous effectuez une étape avec le débogueur, l'outil d'inspection conserve la mise en surbrillance s'il pense qu'elle est toujours applicable. Au départ, cette fonctionnalité n'était pas prévue sur notre feuille de route, mais nous avons rapidement réalisé que cela compromet votre expérience de débogage. Imaginez que vous deviez inspecter à nouveau le tableau après chaque étape, comme dans la vidéo ci-dessous !
Lorsque le débogueur atteint un nouveau point d'arrêt, l'outil d'inspection de la mémoire interroge à nouveau V8 et l'extension pour rechercher la variable associée à la mise en surbrillance précédente. Il compare ensuite les emplacements et les types des objets. Si elles correspondent, la mise en surbrillance persiste. Dans la vidéo ci-dessus, une boucle for écrit dans le tableau x
. Ces opérations ne modifient pas le type ni la position du tableau. Il reste donc en surbrillance.
Vous vous demandez peut-être comment cela affecte les pointeurs. Si vous avez un pointeur en surbrillance et que vous le réattribuez à un autre objet, l'ancienne et la nouvelle position des objets en surbrillance seront différentes, et la mise en surbrillance disparaît. Étant donné que l'objet pointé par le nouveau pointeur peut se trouver n'importe où dans la mémoire WebAssembly et qu'il aura probablement peu de rapport avec l'emplacement de mémoire précédent, supprimer la mise en surbrillance est plus clair que de sauter vers un nouvel emplacement de mémoire. Vous pouvez de nouveau mettre en surbrillance le pointeur en cliquant sur son icône de mémoire dans le volet Champ d'application.
Conclusion
Cet article décrit les améliorations apportées à l'outil d'inspection de la mémoire pour le débogage C/C++. Nous espérons que ces nouvelles fonctionnalités simplifieront le débogage de la mémoire de vos applications C/C++. Si vous avez des suggestions pour l'améliorer, n'hésitez pas à nous les envoyer en signalant un bug.
Étapes suivantes
Pour en savoir plus, consultez les sections suivantes :