wasm-debug
wasm-debug copied to clipboard
Direct, source-level WebAssembly debugger
wasm-debug
Direct, source-level WebAssembly debugger
We're exploring the possibility of direct, source-level debugging of WebAssembly binaries.
rustc/clang compilers can generate DWARF debug info, and embed it into the wasm binaries,
however debuggers like gdb/lldb currently do not know how to work with such files directly.
Status:
- Created
wasm2dbg.pyutility to repackage the DWARF info fromwasmtoelfformat.
The resulting file can be loaded by unmodified versions of debuggers. - Created
gdb-stub.py, which uses GDB Remote Serial Protocol to communicate togdbandlldb.
This is a prototype of a VM that successfully emulates a breakpoint hit.
Next:
- Implement
Wasm3-based opcode-level debugger - Connect
Wasm3togdb/lldbviaRemote Serial Protocol
NOTE: This is work-in-progress, and highly experimental!
This work should actually be a good starting point to start adding direct wasm support to debuggers.
Looks like LLDB already started some movement in this direction (see here and here).
Also, DWARF format has to be extended to allow representing wasm local, global or operand stack variables.
Building test apps
See Rust and C example apps.
Extracting DWARF debug info
./wasm2dbg.py ./test_app_c/app.wasm
# Strip debug info from the wasm file (optional):
wasm-strip ./test_app_c/app.wasm
Debugging
# Using GDB:
./prototype/gdbstub.py &
cd test_app_c
gdb -q -x ../.gdbscript app.wasm.dbg
# Or LLDB:
./prototype/gdbstub.py &
cd test_app_c
lldb -s ../.lldbscript app.wasm.dbg
Examining the GDB RSP protocol
To debug the RSP packets, it's convenient to use tcpdump + tcpflow:
sudo tcpdump -i lo -l -w - port 4444 | tcpflow -C -g -r -
Also, debuggers provide built-in logs for this:
GDB:
(gdb) set debug remote 1
GDB, log to a separate file:
(gdb) set remotelogfile gdb-rsp.log
LLDB:
(lldb) log enable gdb-remote packets
Examining the produced wasm binaries
After building the app, it may be interesting to inspect WASM contents.
There are multiple tools for that, here are some examples:
llvm-objdump-10 -h app.wasm
llvm-dwarfdump-10 app.wasm --all -o app.dwarfdump
wasm-objdump -hxd app.wasm > app.objdump
wasm-dis -sm app.wasm.map app.wasm -o app.dis
wasm-decompile app.wasm -o app.decompile
License
This project is released under The MIT License (MIT)