Ich möchte in der Lage sein, das Erstellen eines binären Builders zu debuggen. Im Moment drucke ich im Grunde genommen die Eingabedaten in den binären Parser aus, gehe dann tief in den Code ein und drucke die Zuordnung der Eingabe zur Ausgabe aus, nehme dann die Ausgabezuordnung (Ganzzahlen) und verwende diese, um die entsprechende Ganzzahl zu lokalisieren in der Binärdatei. Ziemlich klobig und erfordert, dass ich den Quellcode tiefgreifend ändere, um die Zuordnung zwischen Eingabe und Ausgabe zu erreichen.
Es scheint, als könnten Sie die Binärdatei in verschiedenen Varianten anzeigen (in meinem Fall möchte ich sie in 8-Bit-Blöcken als Dezimalzahlen anzeigen, da dies ziemlich nahe an der Eingabe liegt). Tatsächlich sind einige Zahlen 16-Bit, einige 8, einige 32 usw. Vielleicht gibt es also eine Möglichkeit, die Binärdatei mit jeder dieser verschiedenen Zahlen anzuzeigen, die auf irgendeine Weise im Speicher hervorgehoben sind.
Ich könnte nur sehen, dass dies möglich ist, wenn Sie tatsächlich einen Visualizer erstellen, der für das tatsächliche Binärformat / -layout spezifisch ist. Es weiß also, wo in der Sequenz die 32-Bit-Nummern sein sollten und wo die 8-Bit-Nummern sein sollten usw. Dies ist eine Menge Arbeit und in manchen Situationen etwas schwierig. Ich frage mich also, ob es einen allgemeinen Weg gibt, dies zu tun.
Ich frage mich auch, wie das Debuggen dieser Art von Dingen derzeit allgemein funktioniert. Vielleicht kann ich mir ein paar Ideen einfallen lassen, was ich daraus machen soll.
Antworten:
Verwenden Sie für Ad-hoc-Überprüfungen einfach einen Standard-Hexdump und lernen Sie, ihn zu betrachten.
Wenn Sie sich für eine ordnungsgemäße Untersuchung ausrüsten möchten, schreibe ich normalerweise einen separaten Decoder in etwas wie Python - idealerweise wird dieser direkt aus einem Nachrichtenspezifikationsdokument oder einer IDL gesteuert und ist so automatisiert wie möglich (es besteht also keine Möglichkeit, ihn manuell einzuführen) der gleiche Fehler in beiden Decodern).
Vergessen Sie nicht, dass Sie Unit-Tests für Ihren Decoder mit bekanntermaßen korrekten Eingaben schreiben sollten.
quelle
Der erste Schritt dazu besteht darin, dass Sie eine Möglichkeit benötigen, eine Grammatik zu finden oder zu definieren, die die Struktur der Daten beschreibt, dh ein Schema.
Ein Beispiel hierfür ist eine Sprachfunktion von COBOL, die informell als Copybook bezeichnet wird. In COBOL-Programmen würden Sie die Struktur der Daten im Speicher definieren. Diese Struktur wurde direkt der Art und Weise zugeordnet, in der die Bytes gespeichert wurden. Dies ist in Sprachen dieser Zeit üblich, im Gegensatz zu gängigen zeitgenössischen Sprachen, in denen das physische Layout des Speichers ein Implementierungsproblem darstellt, das vom Entwickler weg abstrahiert wird.
Bei einer Google-Suche nach der Sprache des Binärdatenschemas werden eine Reihe von Tools angezeigt. Ein Beispiel ist Apache DFDL . Möglicherweise gibt es auch dafür bereits eine Benutzeroberfläche.
quelle
ASN.1 , Abstract Syntax Notation One, bietet eine Möglichkeit, ein Binärformat anzugeben.
quelle
Andere Antworten haben das Anzeigen eines Hex-Dumps oder das Ausschreiben von Objektstrukturen in JSON beschrieben. Ich denke, beide zu kombinieren ist sehr hilfreich.
Die Verwendung eines Tools, mit dem JSON über dem Hex-Dump gerendert werden kann, ist sehr nützlich. Ich habe ein Open-Source-Tool geschrieben, das .NET-Binärdateien mit dem Namen dotNetBytes analysiert hat. Hier ist eine Ansicht einer Beispiel-DLL .
quelle
Ich bin mir nicht sicher, ob ich das vollständig verstehe, aber es hört sich so an, als hätten Sie einen Parser für dieses Binärformat und steuern den Code dafür. Diese Antwort basiert also auf dieser Annahme.
Ein Parser füllt in irgendeiner Weise Strukturen, Klassen oder die Datenstruktur Ihrer Sprache aus. Wenn Sie a
ToString
für alles implementieren, was analysiert wird, erhalten Sie eine sehr einfach zu verwendende und leicht zu wartende Methode, um diese Binärdaten in einem für Menschen lesbaren Format anzuzeigen.Sie hätten im Wesentlichen:
Und das war's, vom Standpunkt der Verwendung. Dies erfordert natürlich, dass Sie die
ToString
Funktion für IhreObject
Klasse / Struktur / was auch immer implementieren / überschreiben , und Sie müssten dies auch für alle verschachtelten Klassen / Strukturen / was auch immer tun.Sie können zusätzlich eine bedingte Anweisung verwenden, um zu verhindern, dass die
ToString
Funktion im Release-Code aufgerufen wird, damit Sie keine Zeit mit etwas verschwenden, das außerhalb des Debug-Modus nicht protokolliert wird.Sie
ToString
könnten so aussehen:Bei Ihrer ursprünglichen Frage klingt es so, als hätten Sie etwas versucht, dies zu tun, und Sie halten diese Methode für lästig, aber Sie haben auch irgendwann das Parsen eines Binärformats implementiert und Variablen zum Speichern dieser Daten erstellt. Sie müssen also nur die vorhandenen Variablen auf der entsprechenden Abstraktionsebene drucken (die Klasse / Struktur, in der sich die Variable befindet).
Dies sollten Sie nur einmal tun müssen, und Sie können dies tun, während Sie den Parser erstellen. Und es ändert sich nur, wenn sich das Binärformat ändert (was ohnehin schon zu einer Änderung Ihres Parsers führt).
In ähnlicher Weise: Einige Sprachen verfügen über robuste Funktionen zum Umwandeln von Klassen in XML oder JSON. C # ist besonders gut darin. Sie müssen Ihr Binärformat nicht aufgeben, sondern führen nur XML oder JSON in einer Debug-Protokollierungsanweisung aus und lassen Ihren Release-Code in Ruhe.
Ich persönlich würde empfehlen, den Hex-Dump-Weg nicht zu wählen, da er fehleranfällig ist (haben Sie mit dem rechten Byte begonnen, sind Sie sicher, dass Sie beim Lesen von links nach rechts die richtige Endianness "sehen" usw.) .
Beispiel: Sagen Sie Ihre
ToStrings
Spuckvariablena,b,c,d,e,f,g,h
. Sie führen Ihr Programm aus und bemerken einen Fehler mitg
, aber das Problem begann wirklich mitc
(aber Sie debuggen, also haben Sie das noch nicht herausgefunden). Wenn Sie die Eingabewerte kennen (und sollten), werden Sie sofort sehen, dassc
hier Probleme beginnen.Im Vergleich zu einem Hex-Dump, der Ihnen nur sagt
338E 8455 0000 FF76 0000 E444 ....
; Wenn Ihre Felder unterschiedlich groß sind, woc
beginnt und was der Wert ist - ein Hex-Editor wird es Ihnen sagen, aber mein Punkt ist, dass dies fehleranfällig und zeitaufwändig ist. Darüber hinaus können Sie einen Test nicht einfach / schnell über einen Hex-Viewer automatisieren. Wenn Sie nach dem Parsen der Daten eine Zeichenfolge ausdrucken, erfahren Sie genau, was Ihr Programm "denkt", und dies ist ein Schritt auf dem Weg zum automatisierten Testen.quelle