Skip to content

Add basic CI check for "debuggability" via Chrome devtools #5

Description

@sethp

Debugging via the chrome devtools requires all of:

  1. The binary object file
  2. The .debug_info DWARF data
  3. The source file

Emscripten allows for three useful arrangements of the first two:

a. Binary + DWARF in one large file—but, DWARF is usually bigger than the code itself, and this makes everyone pay to download that data. Plus, it doesn't actually matter when it comes to locating the sources.
b. -gseparate-dwarf=... passed to the compiler , which strips all but a single "extern_debug_info" section from the resulting binary (more info: https://developer.chrome.com/blog/wasm-debugging-2020/#separate-dwarf )
c. -gsplit-dwarf passed to the linker, along with packaging (e.g. via emdwp) all of the resulting .dwo files into a single .dwp as a final post-processing step. The latter is necessary because emdwp doesn't create a pointer section, so the Chrome devtools just guess "hey file.wasm probably has its debug package at file.wasm.dwp"

(hmm, I wonder if I could emdwp the separate'd dwarf info? as a way to get the minimum size without needing to serve all the .dwo assets?)

As for the sources, I have no idea where header references even live, but for everything else the top-level compilation units have a "name" (and a comp_dir, that sometimes matters). The chrome devtools really like looking for file://... paths to the sources, which is really unfortunate: it means that the debug_info filenames have to match the layout of the filesystem exactly, which they don't even On My Machine (never mind CI or over the web) because of the reproducibility work I put in, which means it's all built via Docker.

So, the ways I've tricked the Chrome devtools into looking for the sources at a different place are:

  • local symlink: kinda-sorta works for first party sources, except the state of the file and the state of the binary/debug info will all get out of sync with each other as development happens. Also, for extra fun, any pre-compiled binaries (like, say, in emsdk) have encoded their CI's build path (/emsdk/emscripten) which doesn't even match the official docker container (/emsdk/upstream/emscripten)
  • convince the build toolchain to write down a different path at build time; really there's only one finnicky option for this, -ffile-prefix-map (see: https://reproducible-builds.org/docs/build-path/ ), but getting that + -fdebug-compilation-dir + the Chrome devtools' (unwritten) expectations all lined up is not easy to generalize (i.e. what works for talvos doesn't work for SPIRV-Headers)

DWARF also permits embedding the sources directly, but neither the Emscripten nor Chrome devtools seem prepared to take advantage of that.

So, some options:

  • expand or replace my dwarf.rs tool to print out the file paths that are referenced from the debug info, so it's at least possible to build an inventory of what's there & missing (which also implicitly means codifying our understanding of the Chrome devtools' discovery rules)
  • use -gembed-sources (oops, is that a compile option?) and:
    • teach the chrome devtools (& vscode wasm debugger) to respect the embedded sources
    • build a tool that rips the sources back out again and explodes them into some directory structure which matches how they'll be looked for (if the latter's even possible)
  • dive into the emcc frontend implementation of -gseparate-dwarf &/ linker &/ other DWARF post-processors like emdwp; maybe I'll get lucky & there's a tool for doing the post-processing remapping already? Maybe I'd have to write it myself?

But, at the end of the day, what we need is a little light on the CI system that can look at a .wasm payload and say "ok!" as to its debuggability. That's closest to dwarf.rs, +/- doing some checking around what areas are covered (or not covered) by debug symbols (though, a first pass there is probably just "does it have debug symbols at all?")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions