Photo: Intricate Explorer, Unsplash
Aujourd'hui, je me suis souvenu de l'un de mes "mythes de programmation" préférés, qui pourrait très bien être une légende urbaine, et de ma propre version de la "boîte noire" qui nécessitait un débogage.
La légende urbaine raconte les wagons radioactifs d'Ukraine qui ont causé des bugs dans le système informatique, vous pouvez la lire ici .
Nous traitons les "boîtes noires" et ce qu'elles sont aujourd'hui
Une boîte noire est un concept de programmation populaire qui suppose que nous sommes en dehors d'un système ou d'un composant sans accès direct au code. Cela peut être causé par divers facteurs:
- Vous travaillez avec des logiciels tiers dont les développeurs ne divulguent tout simplement pas le code.
- Vous interagissez avec une API dont la logique interne est abstraite.
- Vous ne disposez pas des autorisations nécessaires pour accéder au référentiel Git.
- Même un système avec un accès complet peut devenir de facto une boîte noire en raison de sa complexité.
- Un employé qui possédait toutes les clés et toutes les connaissances quittera / disparaîtra / mourra soudainement.
- Le système hérité se compose d'un fichier .dll qui «fonctionnait toujours» sur le serveur et qui n'était pas connecté à un système de contrôle de version. Pour simplement regarder le code, vous devez le décompiler, si possible, bien sûr.
Tous ces facteurs se résument au fait que nous avons un problème que nous ne pouvons pas résoudre instantanément et que nous ne savons pas quelle est l'erreur. Par conséquent, nous devons nous mettre au travail.
Notre propre problème était une combinaison de tout ce qui précède
La liste des facteurs énumérés ci-dessus ne couvre probablement pas toutes les situations, car il s'agit d'une liste directe de facteurs qui ont influencé notre situation. Nous venions de licencier un développeur, un système complexe réparti sur plusieurs serveurs, avec un noyau .dll qui «faisait son travail», même si personne ne savait pourquoi ni lequel.
Il appelait des services tiers, il n'y avait pratiquement pas de connexion, et les seules sauvegardes que nous avions étaient les stockages dans le système de fichiers avec ce .dll
et sans aucun code. Comme vous pouvez le comprendre, rien de tout cela n'a pu être maintenu et ils prévoyaient de réécrire le système en temps voulu, mais l'erreur était urgente et nécessitait une élimination.
Nous pouvons dire que la plupart du temps, le système faisait presque complètement face au travail et que nous pourrions accepter des solutions partielles au problème si elles faisaient preuve de cohérence. Cependant, environ chaque centième ensemble de données s'est avéré avoir des résultats incorrects et la seule chose que nous pouvions faire était de les déboguer de l'extérieur (maintenant nous nous en souvenons avec le sourire).
C'est l'un de ces moments où je me suis senti reconnaissant pour le monde chaotique dans lequel j'ai grandi, car la plupart des entreprises ne seront pas confrontées à des problèmes aussi graves et ne nommeront pas un diplômé récent pour les résoudre. J'ai eu de la chance dans ce sens, et encore plus de chance, car j'avais le soutien de développeurs expérimentés qui m'ont aidé tout au long du processus. C'était donc notre solution.
Nous reproduisons l'erreur (idéalement sur plusieurs cas de test)
Une fois que vous savez quel est le vrai bogue, le problème est presque résolu, mais il peut être incroyablement difficile d'y accéder si le bogue se produit de manière irrégulière. Repensez à l'exemple de train - s'il n'était pas possible d'identifier le modèle, alors la raison serait presque impossible à trouver. Parce que c'est ce que nous recherchons dans une telle situation - le schéma du moment où une erreur se produit.
Dans notre cas, nous l'avons trouvé relativement simplement: nous connaissions le type d'erreur et cela s'est produit à plusieurs reprises, mais si rarement qu'il nous a fallu plusieurs fois pour réduire l'espace de recherche des cas et révéler leur logique.
Après avoir identifié de nombreux cas de test qui conduisent régulièrement à des échecs, vous pouvez commencer à se déboguer. Voici un exemple d'un autre processus dans lequel nous avons restreint la recherche de la source du problème en faisant correspondre des modèles: l'un des systèmes s'est bloqué tous les jeudis soirs et il n'y avait rien d'étrange dans les fichiers journaux:
- Nous savions que notre système ne donnait aucun message d'erreur, mais il s'est bloqué.
- Nous avons comparé les cas jusqu'à ce que nous soyons sûrs que le problème s'est produit jeudi et aucun autre jour.
- Nous avons vérifié qu'aucune mise à jour automatique n'est prévue pour cette heure, vérifié toutes les tâches automatisées exécutées sur le même serveur - rien.
- Nous avons examiné ce que le système faisait au niveau méta et l'avons réduit à un délai d'expiration du disque partagé, auquel une tâche de nettoyage de disque s'exécutait toutes les deux semaines sur un serveur complètement différent pendant que notre service était en cours d'exécution. Personne ne pensait que tous les deux avaient commencé à se lancer à trois heures du matin.
Créer un environnement de test (même s'il s'agit de production)
Une fois que vous avez un ensemble d'erreurs, vous pouvez commencer à travailler sur la véritable cause et la solution, ce qui nécessite un système de test.
Par cela, je veux dire que vous avez besoin de deux constantes:
- Les données utilisées ne doivent pas être modifiées par d'autres systèmes
- Les dommages éventuels doivent être limités autant que possible
Dans notre cas, nous n'avons pas pu reproduire les erreurs sur le serveur de test, c'était évident, car la bibliothèque .dll était dans un état complètement différent par rapport au serveur en production. Le retour à cet ancien état n'a pas fonctionné car il a brisé d'autres éléments tout aussi importants.
Nous nous sommes donc réunis et avons posé la question: «Quel est le pire qui pourrait arriver si nous gâchions cela?» Et ensuite, nous avons écrit un script de base de données qui réécrirait tous les résultats dans un état d'erreur afin que les systèmes suivants ne les traitent pas.
Il était possible, par exemple, de déconnecter les serveurs et les tâches, de supprimer l'étape logique suivante du processus, etc., mais la possibilité de cela dépend de l'architecture d'un système particulier.
Comparez les données d'entrée pour trouver des similitudes et des différences avec les ensembles de données de travail
Bien que l'on ne puisse pas savoir exactement ce que fait le code dans le cas d'une "boîte noire", il a été possible de réaliser une sorte de "reverse engineering", donnant souvent une bonne compréhension des causes des problèmes.
Dans notre cas, nous avons eu le luxe de fichiers JSON raisonnablement bien formatés du système précédent dont dépendait notre entrée. Après avoir tout configuré, il restait à commencer à comparer littéralement quelques fichiers texte dans Notepad ++ jusqu'à ce que nous trouvions les similitudes entre les fichiers à l'origine des erreurs, puis les différences entre eux et les fichiers fonctionnant correctement.
Nous avons eu de la chance ici - nous avons pu rapidement comprendre que le bogue provoquait une combinaison spécifique de drapeaux clients, et nous avons immédiatement réussi à les contourner, car ce cas pouvait être "imité" avec des drapeaux similaires mais différents. Par conséquent, comme nous savions déjà que le système serait réécrit (en fait, nous n'avions pas le choix), il a été décidé de contourner ce bogue au lieu de le décompiler et de le corriger.
Modification de l'entrée pour s'assurer que notre estimation conduit aux résultats attendus (et limite tout dommage)
Évidemment, c'est une mauvaise idée de changer des données en direct dans une base de données en production, en espérant que tout fonctionnera sans vrais tests, mais nous n'avions pas d'autre choix.
Cela a très bien fonctionné car le nombre de cas était faible et les premiers tests que nous avons exécutés manuellement se sont avérés être exactement ce que nous voulions.
Nous avons donc fini par écrire une autre tâche automatisée pour résoudre ces problèmes avant qu'ils n'atteignent le système, puis nous nous sommes lancés dans un projet de trois mois pour réécrire ce programme à partir de zéro, cette fois de manière transparente, avec contrôle de version et création de pipelines.
Voici une aventure.
Conclusion: vous pouvez en apprendre beaucoup sur le système, même si vous vous contentez de le contourner et de le pousser avec un bâton
Je suis ravi de cette façon de déboguer et de trouver des erreurs, j'adore quand la programmation est combinée avec une poussée d'adrénaline.
Si vous n'avez pas regardé la vidéo sur l'injection SQL et l'ingénierie inverse de la base de données sur les messages d'erreur, je vous recommande vivement de la regarder . Les techniques utilisées dans cette vidéo sont presque identiques à celles qui peuvent être utilisées pour le débogage non malveillant.
Publicité
Commandez et travaillez immédiatement! Création de VDS de n'importe quelle configuration en une minute, y compris des serveurs pour stocker de grandes quantités de données jusqu'à 4000 Go. Epic :)
Abonnez-vous à notre chat sur Telegram .