Eu gostaria de poder depurar a construção de um construtor binário. No momento, estou basicamente imprimindo os dados de entrada no analisador binário e, depois, aprofundando o código e imprimindo o mapeamento da entrada na saída, pegando o mapeamento de saída (inteiros) e usando-o para localizar o número inteiro correspondente no binário. Muito desajeitado e requer que eu modifique o código fonte profundamente para obter o mapeamento entre entrada e saída.
Parece que você pode ver o binário em diferentes variantes (no meu caso, eu gostaria de vê-lo em blocos de 8 bits como números decimais, porque isso é muito próximo da entrada). Na verdade, alguns números são de 16 bits, 8, 32, etc. Então, talvez exista uma maneira de visualizar o binário com cada um desses números diferentes destacados na memória de alguma maneira.
A única maneira de ver que isso é possível é se você criar um visualizador específico para o formato / layout binário real. Portanto, ele sabe onde na sequência os números de 32 bits devem estar e onde os números de 8 bits devem estar etc. Isso é muito trabalhoso e meio complicado em algumas situações. Então, me perguntando se existe uma maneira geral de fazer isso.
Também estou me perguntando qual é a maneira geral de depurar esse tipo de coisa atualmente, então talvez eu possa ter algumas idéias sobre o que tentar com isso.
Respostas:
Para verificações ad-hoc, basta usar um hexdump padrão e aprender a olhá-lo.
Se você deseja se preparar para uma investigação adequada, normalmente escrevo um decodificador separado em algo como Python - idealmente, isso será direcionado diretamente de um documento de especificação de mensagem ou IDL e será o mais automatizado possível (para que não haja chance de introduzir manualmente o mesmo bug nos dois decodificadores).
Por fim, não se esqueça de que você deve escrever testes de unidade para o seu decodificador, usando entradas enlatadas corretas e conhecidas.
fonte
O primeiro passo para fazer isso é que você precisa de uma maneira de encontrar ou definir uma gramática que descreva a estrutura dos dados, isto é, um esquema.
Um exemplo disso é um recurso de linguagem do COBOL, conhecido informalmente como copybook. Nos programas COBOL, você definiria a estrutura dos dados na memória. Essa estrutura foi mapeada diretamente para a maneira como os bytes foram armazenados. Isso é comum nas linguagens daquela época, em oposição às linguagens contemporâneas comuns, nas quais o layout físico da memória é uma preocupação de implementação que é abstraída do desenvolvedor.
Uma pesquisa no google por linguagem de esquema de dados binários exibe várias ferramentas. Um exemplo é o Apache DFDL . Talvez já exista uma interface do usuário para isso.
fonte
ASN.1 , Resumo Sintaxe Notação Um, fornece uma maneira de especificar um formato binário.
fonte
Outras respostas descreveram a exibição de um hex dump ou a gravação de estruturas de objetos no JSON. Eu acho que combinar essas duas coisas é muito útil.
Usar uma ferramenta que pode renderizar o JSON no topo do dump hexadecimal é realmente útil; Eu escrevi uma ferramenta de código-fonte aberto que analisava binários do .NET chamados dotNetBytes . Aqui está uma exibição de um exemplo de DLL .
fonte
Não sei se entendi completamente, mas parece que você tem um analisador para esse formato binário e controla o código. Portanto, essa resposta se baseia nessa suposição.
Um analisador de alguma forma estará preenchendo estruturas, classes ou qualquer estrutura de dados que seu idioma tenha. Se você implementar um
ToString
para tudo o que for analisado, terá um método muito fácil de usar e de manutenção fácil de exibir esses dados binários em um formato legível por humanos.Você teria essencialmente:
E é isso, do ponto de vista de usá-lo. Obviamente, isso exige que você implemente / substitua a
ToString
função da suaObject
classe / struct / qualquer que seja, e você também precisará fazê-lo para quaisquer classes / estruturas / estruturas aninhadas.Além disso, você pode usar uma instrução condicional para impedir que a
ToString
função seja chamada no código de liberação, para não perder tempo com algo que não será registrado fora do modo de depuração.Você
ToString
pode ficar assim:Sua pergunta original faz parecer que você tentou fazer isso de alguma maneira e acha que esse método é oneroso, mas em algum momento também implementou a análise de um formato binário e criou variáveis para armazenar esses dados. Então, tudo o que você precisa fazer é imprimir essas variáveis existentes no nível apropriado de abstração (a classe / estrutura em que a variável se encontra).
Isso é algo que você deve fazer apenas uma vez e pode fazê-lo enquanto cria o analisador. E isso só será alterado quando o formato binário for alterado (o que já solicitará uma alteração no seu analisador de qualquer maneira).
Na mesma linha: algumas linguagens possuem recursos robustos para transformar classes em XML ou JSON. C # é particularmente bom nisso. Você não precisa renunciar ao seu formato binário, basta fazer o XML ou JSON em uma instrução de log de depuração e deixar seu código de versão em paz.
Eu, pessoalmente, recomendo não seguir a rota do dump hexadecimal, porque é propenso a erros (você começou no byte certo, tem certeza de que, quando está lendo da esquerda para a direita, está "vendo" a endianness correta etc.) .
Exemplo: diga suas
ToStrings
variáveis cuspira,b,c,d,e,f,g,h
. Você executa o seu programa e percebe um errog
, mas o problema realmente começouc
(mas você está depurando, portanto ainda não percebeu isso). Se você conhece os valores de entrada (e deveria), verá instantaneamente quec
é onde os problemas começam.Comparado a um dump hexadecimal que apenas informa
338E 8455 0000 FF76 0000 E444 ....
; se seus campos têm tamanhos variados, por ondec
começa e qual é o valor - um editor hexadecimal dirá a você, mas o que quero dizer é que isso é propenso a erros e consome tempo. Não apenas isso, mas você não pode automatizar fácil / rapidamente um teste através de um visualizador hexadecimal. A impressão de uma sequência de caracteres após a análise dos dados informará exatamente o que seu programa está "pensando" e será um passo no caminho do teste automatizado.fonte