Home Posts WebAssembly Debugging Cheat Sheet [2026 Reference]
Developer Reference

WebAssembly Debugging Cheat Sheet [2026 Reference]

WebAssembly Debugging Cheat Sheet [2026 Reference]
Dillip Chowdary
Dillip Chowdary
Tech Entrepreneur & Innovator · May 11, 2026 · 11 min read

Bottom Line

For day-to-day browser debugging, use DWARF builds in Chrome; for optimized or more portable location mapping, emit source maps. When variables disappear or layouts look wrong, inspect raw linear memory directly instead of guessing.

Key Takeaways

  • DWARF gives the best Wasm source-level debugging; source maps are broader but mostly location-only.
  • In Emscripten, debug output is controlled at link time as well as compile time.
  • Chrome Memory Inspector is available from Chrome 91; Wasm object-memory workflows are best on Chrome 107+.
  • Use -g2 for cheap readable stacks, -gsource-map for optimized location mapping, and -gseparate-dwarf to keep shipped Wasm lean.

Wasm debugging is finally practical, but the toolchain still punishes fuzzy build settings. On May 11, 2026, the fastest path is simple: use DWARF when you need variable-aware stepping in Chrome, use source maps when you need optimized location mapping, and drop into Memory Inspector when symbols stop telling the truth. This reference keeps the commands, shortcuts, and configuration edges in one place.

Key Takeaways

  • DWARF gives the richest browser debugging experience; source maps are broader but mostly map locations.
  • With Emscripten, debug behavior is controlled at link time too, not only when compiling objects.
  • Chrome 91+ ships Memory Inspector; Chrome 107+ improves Wasm object-memory inspection for C/C++ debugging.
  • -g2, -gsource-map, and -gseparate-dwarf solve different problems. Pick deliberately.

Debugging Stack at a Glance

Bottom Line

Use DWARF for real source-level browser debugging, use source maps for optimized line mapping, and use Memory Inspector when byte-level truth matters more than symbol fidelity.

Emscripten officially supports both DWARF and source maps for source-level debugging. The tradeoff is straightforward:

  • DWARF offers the best debugging experience in Chrome, including better variable and call-stack inspection.
  • Source maps are more widely supported, but they mainly provide source location mapping and are not a substitute for rich variable inspection.
  • Memory Inspector complements both by exposing the raw WebAssembly.Memory buffer.
  • Debug preservation is not automatic. In Emscripten, the final output still depends on link-time flags.

Pick the right artifact

  • Choose DWARF for browser stepping, locals, scopes, and better inline-aware traces.
  • Choose source maps when you want optimized output and source line mapping without shipping full DWARF in the main binary.
  • Choose -g2 when you mainly want readable function names and low overhead.
  • Choose separate DWARF when production payload size matters but developers still need source-level debugging.
Watch out: Compiling object files with -g is not enough by itself. Emscripten decides what survives into the final Wasm at link time too.

Keyboard Shortcuts

These are the high-value shortcuts to keep your hands off the mouse while debugging Wasm in the Sources panel.

ActionmacOSWindows / Linux
Open DevToolsCommand+Option+IF12 or Control+Shift+I
Open Command MenuCommand+Shift+PControl+Shift+P
Pause / Resume script executionF8 or Command+\F8 or Control+\
Step over next function callF10 or Command+'F10 or Control+'
Step into next function callF11 or Command+;F11 or Control+;
Step out of current functionShift+F11 or Command+Shift+;Shift+F11 or Control+Shift+;
Continue to a certain line while pausedHold Command and click the lineHold Control and click the line
Go to lineControl+GControl+G

Commands by Purpose

Filter the snippets below by flag, tool, or use case.

Full DWARF for stepping and locals

  • Use when you want the best Chrome debugging experience.
  • Best fit for local development and breakpoint-heavy sessions.
emcc -g source.cc -o app.html

Source maps for optimized location mapping

  • Generate DWARF in objects first, then emit the Wasm source map at link time.
  • Use --source-map-base when maps are hosted outside the app directory.
emcc source.c -c -o source.o -g
emcc source.o -o app.js -gsource-map --source-map-base https://debug.example.com/maps/

Inline source maps for self-contained debugging

  • Useful for temporary repro builds and demos.
  • Expensive in file size because source content is embedded.
emcc source.c -c -o source.o -g
emcc source.o -o app.js -gsource-map=inline

Sidecar DWARF for lean shipped Wasm

  • Keeps the main Wasm lighter.
  • Lets DevTools find debug info through a separate file.
emcc -g source.cc -o app.html \
  -gseparate-dwarf=app.debug.wasm \
  -sSEPARATE_DWARF_URL=https://debug.example.com/dwarf/app.debug.wasm

Cheap readable stacks with -g2

  • Preserves function names via the Wasm name section.
  • Good default when full symbolic debugging is overkill.
emcc source.c -c -o source.o
emcc source.o -o app.js -g2

Production symbolication with line tables only

  • Use -gline-tables-only when you need line info but not full type and variable detail.
  • Strip the shipped binary while retaining a debug copy for postmortems.
emcc source.c -c -o source.o -gline-tables-only
emcc source.o -o program2.js -g
llvm-strip program2.wasm -o program2_stripped.wasm

Runtime guards for memory and logic issues

  • ASSERTIONS catches common runtime mistakes.
  • SAFE_HEAP adds extra memory access checks when you are chasing invalid writes or alignment issues.
emcc -O1 -sASSERTIONS test/hello_world.c
emcc -O1 -sSAFE_HEAP=1 test/hello_world.c

Console-level memory inspection

  • Use browser console expressions when you already know the address or pointer range.
  • Useful when locals are optimized away or when you want exact byte views.
new Uint8Array(wasmMemory.buffer, ptr, len)
new DataView(wasmMemory.buffer).getUint32(ptr, true)
new DataView(wasmMemory.buffer).getFloat64(ptr, true)

Configuration

Default recipes

  • Local stepping build: compile and link with -g, then debug in Chrome with the C/C++ DevTools Support (DWARF) extension.
  • Optimized repro build: compile with -g, link with -gsource-map, and keep your normal optimization settings.
  • Small production binary with debug fallback: use -gseparate-dwarf and host the sidecar through SEPARATEDWARFURL.
  • Fast developer stacks: use -g2 when you only need names and readable stack traces.

Path and hosting fixes

  • Use --source-map-base to point the generated Wasm at the correct source-map host.
  • Use -sSOURCEMAPPREFIXES=/old/path=/new/path to rewrite source paths inside the map.
  • If you build on a different machine or inside a container, Chrome's C/C++ DevTools Support (DWARF) extension can remap old and new file paths.
emcc source.c -c -o source.o -g
emcc source.o -o app.js \
  -gsource-map \
  --source-map-base https://debug.example.com/maps/ \
  -sSOURCE_MAP_PREFIXES=/build/src=/src
Pro tip: If your only goal is readable crash output during active development, start with -g2. It is dramatically cheaper than shipping or parsing full DWARF.

Memory Inspection

Memory Inspector is available from Chrome 91. For full Wasm object-memory workflows in C/C++, Chrome documents the best experience on Chrome 107+ with the C/C++ DevTools Support (DWARF) extension installed.

How to open it

  • From DevTools: More tools > Memory inspector.
  • While paused: click Reveal in Memory Inspector from the variable in Scope.
  • You can inspect multiple objects at once in separate tabs.

What it is good at

  • Jumping to exact addresses in hex.
  • Switching between big-endian and little-endian views.
  • Reading integer and floating-point interpretations without writing ad hoc parsing code.
  • Following Pointer 32-bit and Pointer 64-bit jump targets when the addresses are valid.
// Common console helpers while paused
const bytes = new Uint8Array(wasmMemory.buffer, ptr, len)
const dv = new DataView(wasmMemory.buffer)
const u32 = dv.getUint32(ptr, true)
const f64 = dv.getFloat64(ptr, true)

Safe workflow for real incidents

  • Pause at the suspect write or read.
  • Inspect the source-level variable first through DWARF.
  • If the value looks impossible, open Memory Inspector and validate the backing bytes.
  • Before sharing copied buffers or dumps externally, scrub secrets with the Data Masking Tool.

Advanced Usage

When DWARF beats source maps

  • DWARF carries richer type, variable, and inline information.
  • Source maps survive aggressive post-link optimization better and are easier for broad ecosystem tooling.
  • If stack accuracy matters more than portability, prefer DWARF.

Profiling caveat

  • Chrome documents that when DevTools is open for Wasm debugging, the code it runs is not optimized; it is tiered down for a better debugging experience.
  • Do not trust console.time() or performance.now() collected under an attached DevTools session as your primary performance signal.
  • Use the Performance panel, or profile without DevTools open and inspect output afterward.

Minimal decision matrix

  • Need variables, scopes, and line stepping: use -g.
  • Need optimized line mapping without full symbolic payload: use -gsource-map.
  • Need small artifacts plus later debugging: use -gseparate-dwarf.
  • Need readable names only: use -g2.
  • Need production crash line info with less debug bulk: use -gline-tables-only.

Official references checked

Frequently Asked Questions

Should I use DWARF or source maps for WebAssembly debugging? +
DWARF is the better choice when you want real source-level debugging, variable inspection, and stronger call-stack fidelity in Chrome. Source maps are better when you need optimized builds with source-location mapping or wider tooling compatibility, but they do not replace rich symbolic inspection.
Why are my local variables missing in optimized Wasm builds? +
This usually happens because the build kept too little debug information or optimization rewrote the code enough that locals are no longer recoverable in a friendly way. In Emscripten, remember that debug preservation is controlled at link time too, so compiling objects with -g alone is not sufficient.
How do I inspect WebAssembly linear memory in Chrome DevTools? +
Open Memory Inspector from DevTools or reveal a paused variable directly from the Scope pane. For Wasm object-memory workflows in C/C++, Chrome documents the strongest experience on Chrome 107+ with the C/C++ DevTools Support (DWARF) extension.
How do I ship a small Wasm file but keep source-level debugging? +
Use -gseparate-dwarf so the main Wasm omits embedded debug info while a sidecar debug file is generated. If the sidecar lives elsewhere, point to it with -sSEPARATE_DWARF_URL=... so DevTools can resolve it.

Get Engineering Deep-Dives in Your Inbox

Weekly breakdowns of architecture, security, and developer tooling — no fluff.

Found this useful? Share it.