A comprehensive debugging solution that enables LLDB debugging of WebAssembly code running in JavaScriptCore's IPInt (In-Place Interpreter) tier through the GDB Remote Serial Protocol.
Related Documentation:
- This document: JSC debug server implementation (both Standalone and RWI modes)
- RWI_ARCHITECTURE.md: WebKit integration architecture (RWI mode details)
- Debugger-Mutator-Protocol.md: Thread synchronization protocol and control flow diagrams
This project implements a WebAssembly debugger server that bridges the gap between LLDB (the LLVM debugger) and WebAssembly code execution in JavaScriptCore. It allows developers to:
The implementation follows the GDB Remote Serial Protocol standard with wasm extension.
┌─────────────────────────────────────────────────────────────────┐
│ LLDB Debugger │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Breakpoints │ │ Symbol Lookup │ │ Execution Ctrl │ │
│ │ Management │ │ & Modules │ │ & Stepping │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ GDB Remote Protocol (TCP:1234)
│
┌─────────────────────────────▼───────────────────────────────────┐
│ WasmDebugServer │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │Execution Handler│ │ Memory Handler │ │ Query Handler │ │
│ │(Breakpoints) │ │ (WASM Memory) │ │(Capabilities) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Module Manager │ │Breakpoint Mgr │ │ │ │
│ │ (Virtual Addrs) │ │(Helper Class) │ │ │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ Module Tracking & Execution Hooks
│
┌─────────────────────────────▼───────────────────────────────────┐
│ JavaScriptCore WebAssembly Engine │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │JSWebAssemblyMod │ │ IPInt Execution │ │ Debug Info │ │
│ │(Module Tracking)│ │ (Interpreter) │ │ (PC Mapping) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
WasmDebugServer.h/cppThe debugger uses a sophisticated virtual address encoding system to present WebAssembly modules and memory to LLDB:
Address Format (64-bit):
- Bits 63-62: Address Type (2 bits)
- Bits 61-32: ID (30 bits) - ModuleID for code, InstanceID for memory
- Bits 31-0: Offset (32 bits)
Address Types:
- 0x00 (Memory): Instance linear memory
- 0x01 (Module): Module code/bytecode
- 0x02 (Invalid): Invalid/unmapped regions
- 0x03 (Invalid2): Invalid/unmapped regions
Virtual Memory Layout:
- 0x0000000000000000 - 0x3FFFFFFFFFFFFFFF: Memory regions
- 0x4000000000000000 - 0x7FFFFFFFFFFFFFFF: Module regions
- 0x8000000000000000 - 0xFFFFFFFFFFFFFFFF: Invalid regions
gdb-remote localhost:1234: Attach to debuggerprocess interrupt, ctrl+C: Stop execution at function entrycontinue: Resume WebAssembly executionbreakpoint set: Set breakpoints at virtual addressesstep over: Step over function callsstep in: Step into function calls and exception handlersstep out: Step out of current functionstep instruction: Single step through bytecodetarget modules list: List loaded WebAssembly modulesdisassemble: Display WebAssembly bytecodebt (backtrace): Show WebAssembly call stackframe variable: List local variablesmemory region --all: List memory regionsmemory read: Read WebAssembly memory and module sourcememory write: Write to memory? source? or both?The debugger includes comprehensive unit tests that validate debug info generation for WebAssembly opcodes:
# Run unit tests via WebKit build system ./Tools/Scripts/run-javascriptcore-tests --testwasmdebugger
Opcode Coverage (Base OpType):
Extended Opcode Coverage:
The JSTests/wasm/debugger includes a comprehensive test framework with auto-discovery, parallel execution, and process isolation capabilities:
# Run comprehensive test framework with LLDB and wasm debugger python3 JSTests/wasm/debugger/test-wasm-debugger.py
For details, see JSTests/wasm/debugger/README.md.
Standalone Mode (JSC Shell):
Terminal 1 - Start JSC with debugger:
cd JSTests/wasm/debugger/resources/add VM=<Path-To-WebKitBuild>/Debug && DYLD_FRAMEWORK_PATH=$VM lldb $VM/jsc -- --verboseWasmDebugger=1 --wasm-debugger --useConcurrentJIT=0 main.js
Terminal 2 - Connect LLDB:
lldb -o 'log enable gdb-remote packets' -o 'process connect --plugin wasm connect://localhost:1234'
RWI Mode (WebKit/WebContent):
See RWI_ARCHITECTURE.md for complete setup instructions including:
--wasm-debugger flagWasmDebugServer.cpp:348-349WasmDebugServer.cpp:472, 484interrupt() race conditions when VMs are not yet executing codeThe following references correspond to the numbered citations used throughout the WebAssembly debugger implementation: