J'aimerais pouvoir déboguer la construction d'un générateur binaire. En ce moment, je suis en train d'imprimer les données d'entrée sur l'analyseur binaire, puis d'aller en profondeur dans le code et d'imprimer le mappage de l'entrée sur la sortie, puis de prendre le mappage de sortie (entiers) et de l'utiliser pour localiser l'entier correspondant dans le binaire. Assez maladroit, et nécessite que je modifie profondément le code source pour obtenir le mappage entre l'entrée et la sortie.
Il semble que vous puissiez voir le binaire dans différentes variantes (dans mon cas, je voudrais le voir en morceaux de 8 bits sous forme de nombres décimaux, car c'est assez proche de l'entrée). En fait, certains nombres sont 16 bits, certains 8, certains 32, etc. Donc, il y aurait peut-être un moyen de visualiser le binaire avec chacun de ces différents nombres mis en évidence en mémoire d'une manière ou d'une autre.
La seule façon dont je pouvais voir que cela était possible était de créer un visualiseur spécifique au format / à la disposition binaire réel. Il sait donc où dans la séquence les numéros de 32 bits devraient être, et où les numéros de 8 bits devraient être, etc. C'est beaucoup de travail et un peu délicat dans certaines situations. Je me demande donc s'il y a une façon générale de le faire.
Je me demande également quelle est la façon générale de déboguer ce type de chose actuellement, alors peut-être que je peux avoir des idées sur ce qu'il faut essayer.
Réponses:
Pour les vérifications ad hoc, utilisez simplement un hexdump standard et apprenez à le regarder.
Si vous voulez vous préparer pour une enquête appropriée, j'écris généralement un décodeur séparé dans quelque chose comme Python - idéalement, il sera piloté directement à partir d'un document de spécification de message ou IDL, et sera aussi automatisé que possible (il n'y a donc aucune chance d'introduire manuellement le même bug dans les deux décodeurs).
Enfin, n'oubliez pas que vous devez écrire des tests unitaires pour votre décodeur, en utilisant une entrée fixe connue.
la source
La première étape pour ce faire est que vous avez besoin d'un moyen de trouver ou de définir une grammaire qui décrit la structure des données, c'est-à-dire un schéma.
Un exemple de ceci est une fonction de langage de COBOL qui est officieusement connue sous le nom de copybook. Dans les programmes COBOL, vous définiriez la structure des données en mémoire. Cette structure correspondait directement à la façon dont les octets étaient stockés. Ceci est commun aux langages de cette époque par opposition aux langages contemporains courants où la disposition physique de la mémoire est une préoccupation d'implémentation qui est éloignée du développeur.
Une recherche google pour le langage de schéma de données binaires fait apparaître un certain nombre d'outils. Un exemple est Apache DFDL . Il peut également y avoir une interface utilisateur pour cela.
la source
ASN.1 , Abstract Syntax Notation One, fournit un moyen de spécifier un format binaire.
la source
D'autres réponses ont décrit la visualisation d'un vidage hexadécimal ou l'écriture de structures d'objets dans JSON. Je pense que combiner les deux est très utile.
L'utilisation d'un outil qui peut rendre le JSON au-dessus du vidage hexadécimal est vraiment utile; J'ai écrit un outil open source qui analysait les binaires .NET appelé dotNetBytes , voici une vue d'un exemple de DLL .
la source
Je ne suis pas sûr de bien comprendre, mais il semble que vous ayez un analyseur pour ce format binaire et que vous en contrôliez le code. Donc, cette réponse est construite sur cette hypothèse.
Un analyseur remplira en quelque sorte les structures, les classes ou toute autre structure de données de votre langage. Si vous implémentez un
ToString
pour tout ce qui est analysé, vous vous retrouvez avec une méthode très facile à utiliser et facilement maintenue pour afficher ces données binaires dans un format lisible par l'homme.Vous auriez essentiellement:
Et c'est tout, du point de vue de son utilisation. Bien sûr, cela vous oblige à implémenter / remplacer la
ToString
fonction pour votreObject
classe / struct / quoi que ce soit, et vous devrez également le faire pour toutes les classes / structs / whatevers imbriquées.Vous pouvez en outre utiliser une instruction conditionnelle pour empêcher la
ToString
fonction d'être appelée dans le code de version afin de ne pas perdre de temps sur quelque chose qui ne sera pas enregistré en dehors du mode débogage.Votre
ToString
pourrait ressembler à ceci:Votre question d'origine donne l'impression que vous avez quelque peu tenté de le faire et que vous pensez que cette méthode est lourde, mais vous avez également à un moment donné implémenté l'analyse syntaxique d'un format binaire et créé des variables pour stocker ces données. Il vous suffit donc d'imprimer ces variables existantes au niveau d'abstraction approprié (la classe / structure dans laquelle se trouve la variable).
C'est quelque chose que vous ne devriez faire qu'une seule fois, et vous pouvez le faire tout en construisant l'analyseur. Et cela ne changera que lorsque le format binaire changera (ce qui entraînera déjà une modification de votre analyseur).
Dans la même veine: certains langages ont des fonctionnalités robustes pour transformer des classes en XML ou JSON. C # est particulièrement bon dans ce domaine. Vous n'avez pas à abandonner votre format binaire, vous faites simplement le XML ou JSON dans une instruction de journalisation de débogage et laissez votre code de version seul.
Je recommanderais personnellement de ne pas emprunter la route de vidage hexadécimal, car elle est sujette aux erreurs (avez-vous commencé sur le bon octet, êtes-vous sûr lorsque vous lisez de gauche à droite que vous "voyez" la bonne endianness, etc.) .
Exemple: dites vos
ToStrings
variables crachéesa,b,c,d,e,f,g,h
. Vous exécutez votre programme et remarquez un bogue avecg
, mais le problème a vraiment commencé avecc
(mais vous déboguez, donc vous ne l'avez pas encore compris). Si vous connaissez les valeurs d'entrée (et vous devriez), vous verrez instantanément quec
c'est là que les problèmes commencent.Comparé à un vidage hexadécimal qui vous dit juste
338E 8455 0000 FF76 0000 E444 ....
; si vos champs sont de taille variable, oùc
commence et quelle est la valeur - un éditeur hexadécimal vous le dira, mais mon point est que cela est sujet aux erreurs et prend du temps. Non seulement cela, mais vous ne pouvez pas automatiser facilement / rapidement un test via une visionneuse hexadécimale. L'impression d'une chaîne après avoir analysé les données vous dira exactement ce que votre programme «pense» et sera une étape sur la voie des tests automatisés.la source