0.2.0 • Published 2 years ago

@jdmichaud/dwarf-2-sourcemap v0.2.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

dwarf-2-sourcemap

Debugging WASM files in the browser is, at the time of this writing, is still an unreliable journey. Chrome has a special extension for this but Firefox does not. So if you are a loyal Firefox user, your out of luck.

But despair not, this project purposes it to use the debugging symbol present in your WASM file in order to generate a sourceMap comprehensible by Firefox (and incidentally Chrome).

This tool reads the DWARF debug symbols that are present in your WASM file, if your compiler included them, and generate, on the fly and in the browser, the corresponding sourceMaps that are then embedded inline in the WASM buffer. Instantiating your module with that "patched" buffer should allow you to debug your WASM source code.

⚠️ This is still a work in progress ! PR welcomed.

Usage

To use it, download the d2sm.js solution and serve it. Then, in your code, before instantiating the WASM module, call patchWithSourceMap providing the arrayBuffer containing the WASM code.

See test.js for an example usage:

async function main() {
  const wasmFile = await fetch('main.wasm');
  const sourceBuffer = await wasmFile.arrayBuffer();
  // Patch the WASM arrayBuffer with an inline sourceMap section corresponding
  // to your DWARF symbol.
  const sourceBufferWithDebug = patchWithSourceMap(sourceBuffer);
  // Repackage the Response for instantiateStreaming below.
  const wasmFileWithDebug = new Response(sourceBufferWithDebug, {
    headers: {
      'Content-Type': 'application/wasm'
    }
  });
  const memory = new WebAssembly.Memory({ initial: 1 });
  const arrayBuffer = memory.buffer;
  const buffer = new Uint8Array(arrayBuffer);
  // Please note that the WebAssembly.instantiate API on firefox is buggy:
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1787593
  const wasm = await WebAssembly.instantiateStreaming(wasmFileWithDebug, {
    env: {
      memory,
      log: (offset, size) => {
        console.log(textDecoder.decode(new Uint8Array(memory.buffer, offset, size)));
      },
    },
  });

  console.log(wasm.instance.exports.add(2, 3));
}

window.onload = main;

References

To dump the DWARF info of a wasm file:

llvm-dwarfdump-14 -debug-info -debug-line --recurse-depth=0 main.wasm > main.dwarf 

To embed the sourcemap in the wasm:

python3 wasm-sourcemap.py --dwarfdump-output main.dwarf main.wasm --output main.wasm.sourcemap -u http://localhost:8000/main.wasm.sourcemap -w main2.wasm 

Example implementation:

Note: From the .debug_info custom section, we are interested in the top level DIEs (the compilation units) in order to retrieve the "DW_AT_comp_dir".

Acknowledgement