Usando Browsers Para Debugar Webassembly

Debugar é um passo inevitável do desenvolvimento. Browsers já têm suporte para se debugar Webassembly, Firefox Developer Edition tem as melhores características, enquanto que o Chrome tem característica que complementam Firefox. Neste artigo, eu apresentarei como habilitar o debug durante o processo de compilação, e o que podemos fazer com Firefox e Chrome. Num futuro artigo, focarei no debug de pobre, ou como instrumentar seu código Webassembly para logar mensagens de debug.

Você ouviu aquela do CEO debugando código de noite? Eu também não.

Código Usado Como Exemplo

A seguir é o conteúdo do arquivo xor.c usado para este teste:


unsigned int xor( unsigned int a, unsigned int b)
{
    return a^b;
}

O arquivo xor.c será compilado como uma shared library, desta maneira nós podemos evitar todo o código Javascript auxiliar gerado por Emscripten e podemos focar em debugar.

Aqui está o conteúdo do arquivo xor.html que exercita a função xor:


<html>
<head>
  <script>
    // Currently a Webassembly shared library needs to be fed a memory for its
    // internal stack (see xor.wast exports)
    // In the code below, 256 are Webassembly pages, each with 64KB, which is insane,
    // but this is the default emscripten value used when compiling a wasm shared library,
    // it maybe changed though, but the default is good for our purpose here.
    // Memory base serves the purpose of allowing multiple modules to share the same
    // memory, so each would have its own portion in memory.
    const importObj = {
        env: {
            memory: new WebAssembly.Memory({initial: 256, maximum: 256}),
            memoryBase: 0,
        }
    };

    // Load the module using the newest Streaming API
    WebAssembly.instantiateStreaming(fetch('xor.wasm'), importObj)
    .then(obj => {
        var exports = obj.instance.exports; // the exports of that instance
        var xor = exports._xor; // Rename _xor to xor 🙂
        // Add a listener to the button so we can execute the xor function when the button is pressed.
        var button = document.getElementById('run');
        button.addEventListener('click', function() {
          var input1 = 0x55;
          var input2 = 0xAA;
          alert('XOR('+input1+','+input2+')=='+xor(input1,input2));
        }, false);
      }
    );
  </script>
</head>
<body>
  <input type="button" id="run" value="click for wasm xor"/>
</body>
</html>

Habilitando Debug em Xor.c

Webassembly debug acontece através de source maps. Source maps já é o método usado para debugar Javascript. Para habilitar source maps, compile xor.c com as seguintes opções: -g4 and –source-map-base http://localhost:8080/

Onde:

-g4 habilita source map.

–source-map-base http://localhost:8080/ indica para o Browser onde procurar pelo arquivo source map. No nosso caso, o arquivo de source map está localizado no mesmo lugar onde xor.html esta localizado:http://localhost:8080/, que é o URL que usaremos para iniciar o nosso código de teste.

A seguir está como eu compilei xor.c:


emcc xor.c -O1 -g4 -s WASM=1 -s SIDE_MODULE=1 -o xor.wasm --source-map-base http://localhost:8080/

Como executar o código:

O arquivo xor.html acima usa a mais nova API, instantiateStreaming(), para carregar o módulo Webassembly, a função instantiateStreaming() requer um servidor para servir um módulo Webassembly. Eu uso o seguinte comando emrun para servir o módulo Webassembly:


emrun --no_browser --port 8080 .

Como Debugar Webassembly Usando o Firefox Developer Edition (version 60.0b2)

Aqui está o Firefox Debug View para o código fonte de alto nível(atalho é CTRL+SHIFT+S):

Firefox-Wasm-Debug-SourceView

Muito a explicar:

A área da esquerda contém o Source tab. Dê um Clique duplo em um dos arquivos para ver seu conteúdo na área central. A imagem acima mostra o arquivo xor.c e um breakpoint na linha 3. O programa está parado por causa do breakpoint. Para habilitar o breakpoint, apenas clique na linha que quer colocar o breakpoint.

A área a direita contém a características do debugger. Como você pode ver em Watch expressions, nós não podemos inspecionar variáveis, a variável a está marcada com (unavailable). O painel de Breakpoint mostra nosso breakpoint na linha 3 de xor.c.

O Scopes panel é interessante para o Webassembly view, a ser mostrado mais a frente.

O que podemos fazer aqui? Basicamente, steps no código e roda-lo.

Aqui está o Firefox Debug View para o código Webassembly:

Firefox-Wasm-Debug-WasmView

Acima nós temos o arquivo xor.wasm aberto. Agora o Scopes panel faz sentido, var0, var1, e var2 são variáveis wasm usadas dentro da função xor. Você pode step nas instruções Webassembly, e ver as variáveis mudando de valores.

Embora correntemente não seja possível inspecionar variáveis de alto nível, é possível inspecionar as variáveis em Webassembly. Embora não seja fácil, já é alguma coisa.

Como Debugar Webassembly Usando Chrome (version 65.0.3325.162)

Chrome Debug View (atalho é CTRL+SHIFT+I):

Chrome-Wasm-Debug-WasmView

No geral, o estado atual do Webassembly debug em Chrome é inferior ao Firefox Developer Edition. Não há suporte para código fonte de alto nível, a visão wasm tem nomes estranhos com muito números neles, toma algum tempo para descobrir qual arquivo abrir.

Mas ele tem uma característica muito interessante que não está presente no Firefox: ele mostra a pilha(stack). Na imagem acima, o código está parado exatamente antes da execução da instrução xor. Ali você pode ver que as variáveis locais estão carregadas na pilha, prontas para serem executadas: 0:170 1:85. Esta é uma maneira legal de entender as instruções Webassembly.

Conclusão

Embora preliminar, já há suporte útil ao debug de Webassembly in Firefox e Chrome. Ainda não ideal, mas claramente evoluindo para uma experiência de debug que se possa usar. Futuro artigo demonstrará como debugar Webassembly sem a ajuda do Browser.

Post MindMap

mindmap-in-browser-debugging-webassemblycode

Leave a message below. Webassembly is evolving rapidly, please let me know if this post got outdated.

Enjoyed this post?

Don't miss new posts: Share it with your friends:

Você pode gostar...

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *