Étendre l'outil d'inspection de mémoire pour le débogage C/C++

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 verrons comment nous avons amélioré l'outil d'inspection pour le débogage C/C++ et les difficultés techniques rencontrées.

Voici quelques articles de blog pertinents si vous débutez avec le débogage C/C++ et l'inspecteur de mémoire :

Introduction

L'outil d'inspection de mémoire fournit 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 compter les octets à partir de son début. Dans la capture d'écran ci-dessous, le premier octet d'un tableau int32 à 10 éléments est sélectionné, mais les autres octets qui appartiennent au tableau ne sont pas immédiatement évidents. Ne serait-il pas agréable de pouvoir reconnaître instantanément tous les octets qui appartiennent à l'objet ?

Capture d'écran de l'inspecteur de mémoire d'origine avec un seul octet mis en surbrillance

Mise en surbrillance des objets dans l'outil d'inspection de 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.

Capture d'écran de l'inspecteur de mémoire mis à jour avec un tableau encadré en rouge

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 de la mémoire en surbrillance. Cliquez sur le chip pour accéder à la mémoire de l'objet. Si vous pointez sur le chip, une icône en forme de croix s'affiche. Cliquez dessus pour supprimer la mise en surbrillance.

Lorsque vous sélectionnez un octet en dehors de l'objet que vous inspectez, la mise en surbrillance se désactive pour ne pas 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 plus que jamais l'exploration de la mémoire de vos applications C/C++.

Vous voulez essayer ? Vous devez :

  • Utiliser Chrome 107 ou une version ultérieure
  • Installez l'extension DWARF C/C++.
  • Activez le débogage DWARF dans DevTools > Paramètres. Paramètres > Tests > Débogage WebAssemble: activer la compatibilité 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 factice pour illustrer comment utiliser l'outil d'inspection de la 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 de pointeur pour sélectionner le dernier élément. Malheureusement, le programmeur a commis une erreur dans le calcul du pointeur. Au lieu d'imprimer le dernier élément, le programme imprime des valeurs incompréhensibles.

#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.

Capture d&#39;écran de l&#39;inspecteur de mémoire ouvert avec un tableau int32 inspecté. Tous les éléments du tableau sont mis en surbrillance.

Ensuite, ils révèlent la variable lastNumber dans le volet Scope (Portée) et remarquent que le pointeur pointe vers un entier en dehors du tableau. Fort de ces connaissances, le programmeur se rend compte qu'il a mal compté le décalage du pointeur à la ligne 8. Il aurait dû être ptr + arraySize - 1.

Capture d&#39;écran de l&#39;inspecteur de mémoire ouvert montrant la mémoire mise en surbrillance pointée par un pointeur nommé &quot;lastNumber&quot;. La mémoire mise en surbrillance se trouve juste après le dernier octet du tableau précédemment mis en surbrillance.

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 les outils de développement identifient les éléments à mettre en avant

Dans cette section, nous allons examiner l'écosystème d'outils qui permet le débogage en 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 :

  • L'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 ou C++. Grâce à Emscripten, un compilateur C/C++ vers WebAssembly, vous pouvez compiler des applications compilées en C ou C++ en tant que WebAssembly et les exécuter dans le navigateur.

Lors de la compilation, emscripten intègre les 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 affichez le lastNumber ? Dès que vous cliquez sur l'icône de mémoire, DevTools vérifie la variable que vous souhaitez inspecter. Elle 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 vous indiquer 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'outil d'inspection de la 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é ne figurait pas dans notre feuille de route, mais nous avons rapidement compris que cela compromettait 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 la variable associée à la mise en surbrillance précédente. Il compare ensuite les emplacements et les types des objets. Si les mots correspondent, la mise en surbrillance est conservée. 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 diffèrent et la surbrillance disparaît. Étant donné que l'objet pointé par la nouvelle référence 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 à 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 signaler un bug.

Étapes suivantes

Pour en savoir plus, consultez les sections suivantes :