introduction
Lorsque nous travaillons sur Diablo IV, nous écrivons tout le code sous Windows puis le compilons pour différentes plates-formes. Cela s'applique également à nos serveurs exécutant Linux. (Le code comprend des directives de compilation conditionnelle et, si nécessaire, il contient des fragments écrits spécifiquement pour une plate-forme spécifique.) Notre travail est organisé de cette façon pour de nombreuses raisons. Pour commencer, les compétences professionnelles clés de notre équipe sont Windows. Même nos programmeurs de serveurs sont les plus familiarisés avec le développement Windows. Nous apprécions la possibilité d'utiliser les mêmes outils et la même base de connaissances par tous les programmeurs de notre équipe.
Une autre raison la plus importante pour laquelle nous développons sous Windows est la capacité à tirer parti de l'ensemble d'outils hautement fonctionnels et fiables que Visual Studio nous offre. Et même si nous développions quelque chose sous Linux, alors je peux dire qu'il n'y a rien dans le monde Linux qui puisse même être comparé à Visual Studio.
Certes, à cause de cela, nous sommes confrontés à des difficultés qui surviennent lorsque le serveur tombe en panne et que nous devons déboguer un vidage de la mémoire. Nous avons la possibilité de nous connecter à distance à une machine virtuelle (ou, plus précisément, à un conteneur) qui a échoué, nous pouvons exécuter gdb pour découvrir les raisons de ce qui s'est passé. Mais cette approche présente de nombreux inconvénients. Par exemple - nous ne déployons pas de binaires avec le code source - par conséquent, lorsque vous travaillez avec une machine virtuelle ou avec un conteneur, le code source n'est pas disponible dans la session gdb.
Une autre complication réside dans gdb lui-même. Le fait est que si nous n'utilisons pas cet outil en permanence, de manière régulière, il ne pourra pas être maîtrisé à un niveau qui nous conviendrait. En termes simples, nos développeurs seraient beaucoup plus disposés à utiliser des outils familiers pour déboguer le code. Puisque seulement 2-3 de nos développeurs connaissent très bien gdb, quand quelque chose ne va pas, ce sont eux qui recherchent le problème. Et cela ne peut pas être appelé la répartition optimale de la charge de travail pour les programmeurs.
Nous avons toujours voulu trouver un moyen de déboguer le code Linux qui soit intuitif. C'est pourquoi nous sommes ravis de pouvoir utiliser la nouvelle fonctionnalité Visual Studio qui nous permet de résoudre exactement ce problème dans un environnement familier! Et il ne serait pas exagéré de dire que grâce à cela, notre rêve est devenu réalité.
À propos de notre processus de débogage de code
Le débogage du code Linux dans Visual Studio n'est possible que si le sous-système Windows pour Linux (WSL) est installé sur le système ou si la connexion à Linux est configurée dans Connection Manager . Tous nos développeurs backend ont installé WSL en utilisant la distribution sur laquelle nous déployons notre projet. Nous exécutons un script que j'ai écrit qui installe tous les outils de développement et les bibliothèques de support nécessaires pour construire notre serveur en WSL.
(Je vais m'éloigner de notre sujet principal pendant un moment. Je tiens à souligner que nous sommes arrivés à la conclusion que WSL est le meilleur environnement existant qui permet aux développeurs de tester les changements dans les versions Linux. Ce schéma de travail semble extrêmement pratique: passer à WSL, en utilisant la commande
cd
pour accéder à un répertoire de code partagé et créer le projet directement à partir de là. C'est une bien meilleure solution que d'utiliser une machine virtuelle ou même un conteneur. Si vous créez des projets à l'aide de CMake, vous pouvez également utiliser la prise en charge intégrée de Visual Studio pour WSL .)
Je vais vous parler un peu de nos assemblées. Nous développons le code sous Windows et nous avons une version Windows de notre serveur conçue pour fonctionner sur cet OS. Cela nous est utile lorsque nous travaillons sur les fonctionnalités habituelles du projet. Mais nous déployons notre code côté serveur sur Linux, ce qui nécessite des builds sur Linux. Les assemblys Linux sont créés sur une batterie de construction. Il utilise un système de construction qui s'exécute sur un ordinateur Linux. Avec son aide, notre projet de serveur et le conteneur correspondant sont assemblés, qui sont ensuite déployés. Les binaires Linux sont déployés uniquement dans des conteneurs. Les développeurs n'ont généralement pas accès à ces conteneurs.
Lorsque l'un des serveurs de notre infrastructure tombe en panne, nous en sommes informés par un script spécial, après quoi les fichiers de vidage sont écrits dans un dossier réseau partagé. Pour déboguer ces fichiers, que ce soit sous Linux ou Visual Studio, vous avez besoin d'un programme opérationnel. Lors du débogage, il est utile d'utiliser exactement les mêmes bibliothèques partagées que celles utilisées dans le conteneur déployé. Nous utilisons un script différent pour obtenir ces fichiers. Tout d'abord, nous copions le vidage sur la machine locale, puis nous exécutons le script et lui transmettons des informations sur ce vidage. Le script télécharge le conteneur Docker qui a été construit pour la version testée du code, en extrait les fichiers exécutables de notre serveur, ainsi que certaines bibliothèques d'exécution courantes. Tout cela est nécessaire pour gdb. (Ceci, lorsque vous travaillez avec gdb, évite les problèmes de compatibilité qui pourraient survenir sisi la version WSL du système n'est pas exactement la même que sa version Linux déployée.) Le script, définissant une session de débogage, écrit les données dans
~/.gdbinit
, indiquant que les bibliothèques partagées sont des bibliothèques système.
Ensuite, nous passons à Visual Studio, où le plaisir commence. Nous téléchargeons une solution de build pour la version Windows de nos serveurs. Ensuite, nous ouvrons une nouvelle boîte de dialogue de débogage à l'aide de la commande
Debug -> Other Debug Targets -> Debug Linux Core Dump with Native Only
. Nous cochons la case
Debug on WSL
et entrons les chemins vers les fichiers de vidage et les binaires du serveur (destinés à WSL!). Après cela, appuyez simplement sur le bouton
Debug
et regardez ce qui se passe.
Démarrage du débogage dans Visual Studio
Visual Studio lance automatiquement gdb dans WSL. Une fois que le système a travaillé avec le disque pendant un certain temps, la pile d'appels du programme qui a échoué s'affiche et le pointeur d'instructions est défini sur la ligne de code correspondante. C'est vraiment un nouveau monde courageux!
Ensuite, nous nous occupons de l'identification de l'échec lui-même. Nous avons un gestionnaire d'erreurs qui intercepte l'événement approprié pour exécuter certaines procédures de service. Par conséquent, les informations sur l'échec lui-même se trouvent, sur un serveur monothread, plus profondément dans la pile d'appels. Mais certains de nos serveurs sont multithread. Et le crash peut se produire sur n'importe lequel de leurs threads. Le gestionnaire d'erreurs enregistre des informations sur le code du fichier défectueux et sur le numéro de ligne. Par conséquent, l'examen de ces données nous donne le premier indice. Nous recherchons la place dans la pile d'appels qui correspond à l'exécution de ce code.
Dans l'ancien temps, à savoir il y a quelques semaines, nous aurions utilisé gdb pour remonter tous les threads, puis analyser la liste résultante pour trouver le thread dont la pile d'appels s'est probablement écrasée. Par exemple, si le thread était dans un état dormant, il ne s'est probablement pas planté. Nous avons besoin d'une pile qui contient plus de quelques cadres et des informations que nous traitons avec un thread endormi. Ensuite, nous devons examiner le code afin de comprendre quel est le problème. Si c'est quelque chose de simple, vous pouvez le voir directement dans le code. Si nous sommes confrontés à un problème plus compliqué, nous devrons recourir aux capacités de gdb pour enquêter sur l'état du processus.
Mais Visual Studio nous offre des fonctionnalités bien plus puissantes qu'auparavant. Dans les environnements multithread, vous pouvez ouvrir une fenêtre dans une session de débogage
Threads
et cliquer sur les threads pour afficher leurs piles. Ceci est cependant très similaire à l'approche utilisée dans gdb. Par conséquent, si vous devez étudier, par exemple, 50 threads, cela peut devenir une tâche plutôt fastidieuse et ennuyeuse. Heureusement, Visual Studio dispose d'un outil qui rend cette tâche beaucoup plus facile. Voici la fenêtre Piles parallèles .
J'admets que la plupart d'entre nous ne connaissions pas Parallel Stacks jusqu'à ce qu'Erica Sweet et son équipe nous en parlent. Si pendant la session de débogage exécutez la commande
Debug -> Windows -> Parallel Stacks
- une nouvelle fenêtre s'ouvre, qui affiche des informations sur la pile d'appels de chaque thread dans le processus en cours d'investigation. C'est quelque chose comme une vue d'ensemble de tout l'espace de processus. Tout cadre de pile de n'importe quel thread peut être double-cliqué. Après cela, Visual Studio passera à ce cadre dans la fenêtre de code source et la fenêtre de pile d'appels. Cela nous aide beaucoup à gagner du temps.
Une fois que nous voyons le code à proximité du site de panne, nous pouvons examiner les variables à l'aide de la souris, à l'aide de QuickWatch ou à l'aide de l'un des nombreux outils de Visual Studio. Bien sûr, dans les versions de version, de nombreuses variables sont optimisées, mais en même temps, beaucoup ne le sont pas! Nous, en utilisant l'interface Visual Studio, pouvons identifier le problème beaucoup plus rapidement qu'avant d'utiliser gdb.
Résultat
Notre équipe est ravie de pouvoir déboguer les vidages Linux dans Visual Studio, l'environnement dans lequel nous développons. Pour nous, il s'agit d'une amélioration majeure, car elle permet à beaucoup plus de développeurs que jamais de diagnostiquer les problèmes dans la nature. Cela nous permet à tous de profiter des puissants outils de débogage de Visual Studio. Une fois la préparation préliminaire de l'environnement de travail terminée, vous pouvez participer à une session de débogage Visual Studio en l'espace de quelques minutes. Cette fonctionnalité augmente considérablement la vitesse de recherche des problèmes et l'efficacité de notre travail. Merci à Erica et à son équipe pour leur aide.
Qu'est-ce que vous trouvez le plus utile dans Visual Studio?