# Debugging in Wasmtime
Nick Fitzgerald
2024-02-01
<!-- Put the link to this slide here so people can follow -->
slides: https://hackmd.io/p/-ARJiaL_SAmsWz9DzZUh4Q
---
## Status
* We have discussed all these things before in SIG-Debugging
* I need to wrap this all up in an RFC
* We need to resume and finish in-flight work
* Engineering help very welcome!
---
## The Plan
* Build a Debug Adapter Protocol (DAP) server into Wasmtime
* Leverage existing DAP frontends (VS Code, Emacs, etc)
* "Debugging components" to translate between source and Wasm state
* Use Winch instead of Cranelift for live debugging
---
![](https://github.com/bytecodealliance/meetings/blob/main/SIG-Debugging/2023/layered.png?raw=true)
---
## Incremental Steps
1. **DONE:** Generate Wasm core dumps
2. **TODO:** DAP server w/out stepping, backed by core dumps
* capture core dump in prod, send it to dev for local debugging
4. **TODO:** DAP server w/ stepping, backed by Winch
5. **TODO:** DAP server w/ time travel
* record when running on Cranelift in prod, replay when running on Winch locally?
---
## Single Stepping and Breakpoints
* Reminder: Winch only
* Insert a `nop` between the machine code for each Wasm instruction
* When setting a breakpoint, replace the `nop` with an `int3` (or equiv)
* Catch signal in Wasmtime and notify the debugger thread that the debuggee is paused
---
## Recovering Wasm Debuggee State
* Winch will need to emit debug info tables
* (when in debug mode)
* Indexed by PC, yielding:
* operand stack depth
* which register/SP offset each operand is at
* Locals always at frame base (IIUC)
---
## Watch Points
* Tables, locals, and globals:
* Can implement with breakpoints on every `table.set`, `local.set`, `global.set`, etc instructions
* Memory is a bit trickier:
* Virtual memory tricks to catch writes and then check if they are inside our target memory range
---
## Step Into
* Direct calls:
* set a temp breakpoint at the start of the static callee, continue to it
* Indirect calls:
* break just before the `call_indirect`/`call_ref` transfers control, observe the callee, set a temp breakpoint in the callee
---
## Debugging Components: Why?
* Supports debugging guests running in an interpreter compiled to wasm
* for example, JS
* No need to add new capabilities to guest
* compare to: giving guest a socket to speak its own debugging protocol
---
## Debugging Components: Why?
* No need to spec DWARF interpretation
* Can still wrap existing tooling into debugging components
* but don't *have* to, so door is open to future innovation
---
## Debugging Components
* Each Wasm has a custom section: `debugging_component`
* Contains a URL or file path of this Wasm's debugging component
---
## Debugging Components
* The debugging component imports a `WasmDebugging` WIT interface
* And exports a `SourceDebugging` WIT interface
* Its responsibility is to translate between the two interfaces
---
## Debugging Components
* MVP debugging could skip these, and leave them as an incremental milestone
* Wasmtime would have a built in / fallback DWARF component
* Could implement ourselves with `gimli` or we could wrap `lldb`/`gdb`
* `spidermonkey.wasm` would implement this in terms of calls into SpiderMonkey's `Debugger` API
---
## Record and Replay
Vision: record a trace from prod (Cranelift) and deterministically debug locally (Winch)
---
## Record and Replay
* Recording traces pretty easy
* Capture values passed into Wasm by imports
* Virtual memory tricks to capture memory writes from host imports
* Results of `memory.grow` and `table.grow`
* `NaN` bitpatterns
* Relaxed SIMD stuff
---
## Record and Replay
* Recording even easier at the component layer:
* just interface values crossing the root component boundary, that's it.
---
## Record and Replay
* Replaying also easy!
* hook those same operations to return previously recorded values
---
## Record and Replay
* Time travel debugging harder
* Requires state snapshotting to create keyframes
* Easy for memory, tables, etc...
* Harder for stack and locals
* But again: this can be pushed off as another, later milestone!
* deterministic debugging valuable even without time travel
---
## Next Steps
* I need to polish these ideas into an RFC
* We need to staff this work
---
# Thanks!
{"contributors":"[{\"id\":\"86fa8590-380f-4ee1-8d72-ef8d8b271765\",\"add\":4812,\"del\":281}]","description":"View the slide with \"Slide Mode\".","title":"Debugging in Wasmtime"}