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

Dans Chrome 92, nous avons lancé l'outil d'inspection de mémoire, un outil permettant d'inspecter les tampons de mémoire linéaires. Dans cet article, nous vous expliquons comment nous avons amélioré l'outil d'inspection pour le débogage C/C++ et vous présente les problèmes techniques rencontrés.

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

Introduction

L'outil d'inspection de mémoire fournit des options de débogage plus performantes pour les tampons de mémoire linéaires. Dans le cas de C/C++, vous pouvez inspecter les objets de mémoire C/C++ dans la mémoire WebAssembly.

Reconnaître les octets de votre objet dans la mémoire WebAssembly environnante posait un problème. Vous devez connaître la taille de l'objet et compter les octets à partir du début de l'objet. Dans la capture d'écran ci-dessous, le premier octet d'un tableau int32 à 10 éléments est sélectionné, mais on ne sait pas immédiatement 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 ?

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

Mise en surbrillance des objets dans l'outil d'inspection de mémoire

À partir de Chrome 107, l'outil d'inspection de mémoire met en surbrillance tous les octets d'un objet de mémoire C/C++. Cela vous permet de les distinguer de la mémoire environnante.

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

Regardez la vidéo ci-dessous pour voir l'outil d'inspection de mémoire en action. Lorsque vous affichez le tableau x dans l'outil d'inspection de mémoire, la mémoire en surbrillance s'affiche dans la visionneuse de 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 icône en forme de croix apparaît. 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 s'affaiblit pour éviter de vous distraire. Pour effectuer une nouvelle mise au point, cliquez à nouveau sur l'un des octets de l'objet ou sur le chip.

La prise en charge de la mise en surbrillance des objets ne se limite pas aux tableaux. Vous pouvez également inspecter des structures, des objets et des pointeurs. Grâce à ces modifications, l'exploration de la mémoire de vos applications C/C++ n'a jamais été aussi simple.

Voulez-vous essayer ? Voici ce que vous devez faire:

  • disposer de Chrome 107 ou d'une version ultérieure ;
  • Installez l'extension DWARF C/C++.
  • Pour activer le débogage DWARF, accédez à DevTools > Paramètres. Settings > Experiments > WebAssemble Debugging: Enable DWARF support (Outils de développement > Paramètres > Paramètres > Tests > Débogage de WebAssemble : Activer la prise en charge de 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 pour vous montrer comment utiliser l'outil d'inspection 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 de pointeur pour sélectionner le dernier élément. Malheureusement, le programmeur a fait une erreur dans le calcul du pointeur et au lieu d'imprimer le dernier élément, le programme imprime 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 mémoire pour déboguer le problème. Vous pouvez suivre cette démonstration. Il inspecte d'abord le tableau dans l'outil d'inspection 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;outil d&#39;inspection 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 du volet Scope (Portée) et remarque que le pointeur pointe vers un entier en dehors du tableau. Fort de ces connaissances, le programmeur réalise 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 en surbrillance vers laquelle pointe un pointeur nommé &quot;lastNumber&quot;. La mémoire en surbrillance se trouve juste après le dernier octet du tableau précédemment sélectionné.

Bien qu'il s'agisse d'un exemple jouet, il montre 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 C/C++. Plus précisément, vous découvrirez comment les outils de développement, V8, l'extension DWARF C/C++ et Emscripten rendent possible le débogage C/C++ dans Chrome.

Pour exploiter tout le potentiel du débogage C/C++ dans les outils de développement, vous avez besoin de deux choses:

  • L'extension DWARF C/C++ installée dans Chrome
  • Fichiers sources C/C++ compilés dans 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 comment exécuter C ou C++. Grâce à Emscripten, un compilateur C/C++ pour WebAssembly, vous pouvez compiler des applications créées en C ou C++ en tant que WebAssembly et les exécuter dans le navigateur.

Lors de la compilation, emscripten intégrera 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++, etc. De cette façon, les outils de développement peuvent afficher vos variables C++ bien que V8 exécute WebAssembly. Si vous êtes curieux, consultez cet article de blog pour voir un exemple de données de débogage DWARF.

Que se passe-t-il réellement lorsque vous affichez lastNumber ? Dès que vous cliquez sur l'icône de mémoire, les outils de développement déterminent quelle variable 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'outil d'inspection de mémoire peut afficher la tranche de mémoire pertinente. En 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 la puce de l'outil d'inspection de mémoire indique *lastNumber: int. Qu'est-ce que cela donne ? 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'outil d'inspection vous indiquera vers quoi il pointe.

Conserver les points forts lors des étapes du débogueur

Lorsque vous affichez un objet dans l'outil d'inspection de mémoire et que vous entrez en contact avec le débogueur, l'outil conserve la mise en surbrillance s'il pense qu'il est toujours applicable. Au départ, nous ne disposions pas de cette fonctionnalité dans notre feuille de route, mais nous avons rapidement réalisé que cela compromet votre expérience de débogage. Imaginez devoir inspecter à nouveau le tableau après chaque étape, comme dans la vidéo ci-dessous !

Lorsque le débogueur rencontre un nouveau point d'arrêt, l'outil d'inspection de mémoire interroge à nouveau V8 et l'extension pour la variable associée à la mise en surbrillance précédente. Il compare ensuite l'emplacement et les types des objets. Si elles correspondent, la mise en surbrillance persiste. La vidéo ci-dessus présente une écriture en boucle For dans le tableau x. Ces opérations ne modifient pas le type ni la position du tableau. Celui-ci reste donc mis en surbrillance.

Vous vous demandez peut-être comment cela affecte les pointeurs. Si vous avez un pointeur en surbrillance et que vous l'avez réaffecté à un autre objet, l'ancienne et la nouvelle position des objets en surbrillance sont différentes, et la mise en surbrillance disparaît. Étant donné que l'objet qui vient d'être pointé peut se trouver n'importe où dans la mémoire WebAssembly et aura probablement peu de lien avec l'emplacement de mémoire précédent, il est plus clair de supprimer la mise en surbrillance que de passer à un nouvel emplacement de mémoire. Vous pouvez à nouveau mettre le pointeur en surbrillance en cliquant sur son icône de mémoire dans le volet Scope (Champ d'application).

Conclusion

Cet article décrit les améliorations que nous avons apportées à l'outil d'inspection de 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 encore, n'hésitez pas à nous signaler un bug.

Et ensuite ?

Pour en savoir plus, consultez les sections suivantes :