@@ -7,7 +7,9 @@ Verification's local Stellar testnet built on K formal semantics.
77komet-node executes a whole transaction and returns the * entire* execution trace
88as JSON Lines (one record per WebAssembly instruction) via its ` traceTransaction `
99RPC. This extension loads that trace and lets you ** step forward and backward**
10- through the execution inside VSCode's debugger UI.
10+ through the execution inside VSCode's debugger UI — at the ** Rust source level**
11+ when DWARF debug info is available, and at the instruction level in VSCode's
12+ built-in ** Disassembly View** always.
1113
1214## Status
1315
@@ -32,20 +34,58 @@ through the execution inside VSCode's debugger UI.
3234 JSON-RPC; ` TurnkeyPipeline ` orchestrates build → spawn → seed → deploy →
3335 invoke-with-trace → replay. ` attach ` mode connects to a running node.
3436
35- See [ the roadmap] ( #roadmap ) for what's next.
37+ ** Milestones M4+M5 (done): DWARF → Rust source mapping + DAP disassembly.**
38+
39+ - The build injects ` CARGO_PROFILE_RELEASE_DEBUG=true ` /
40+ ` CARGO_PROFILE_RELEASE_STRIP=none ` into ` stellar contract build ` , so the wasm
41+ carries DWARF — no ` Cargo.toml ` changes needed (set ` "debugInfo": false ` in
42+ the launch config to opt out). The ** pristine linker output**
43+ (` target/…/release/deps/*.wasm ` ) is used and uploaded, because the Stellar
44+ CLI's metadata-injection step rewrites the wasm and strips the DWARF line
45+ programs.
46+ - An in-repo DWARF v4/v5 line-table parser (` src/dwarf/ ` ) maps wasm code
47+ offsets to Rust ` file:line ` . Stack frames open the real ` .rs ` file;
48+ ** breakpoints set in Rust source** verify against the executed trace (sliding
49+ forward to the nearest executed line); stepping is ** statement-granular** in
50+ source and ** instruction-granular** in the Disassembly View
51+ (` supportsSteppingGranularity ` ).
52+ - The raw WebAssembly view is VSCode's built-in ** Disassembly View**
53+ (right-click a stack frame → * Open Disassembly View* ): a static
54+ ` wasmparser ` -backed disassembly with Rust line annotations, plus
55+ ** instruction breakpoints** (` supportsDisassembleRequest ` ,
56+ ` supportsInstructionBreakpoints ` , ` supportsBreakpointLocationsRequest ` ).
57+ - ** No-DWARF fallback:** a prebuilt wasm without debug info, or a ` rawTrace `
58+ replay without ` wasmPath ` , degrades to disassembly-only debugging — frames
59+ carry an instruction pointer but no source.
60+
61+ Trace positions are ** validated** before use: komet-node's ` pos ` is relative to
62+ the section being executed (code section for function code, e.g. the globals
63+ section for global initializers), so every record is cross-checked against the
64+ static disassembly and only trusted when the mnemonics agree. Note that
65+ komet-node's tracer stops at instructions it cannot decode (it prints them as
66+ ` unknown ` , e.g. ` if ` ), so a trace can be a prefix of the full execution.
3667
3768## Verification
3869
39- The replay logic and pipeline are exercised by 38 tests (` npm test ` ):
70+ The replay logic and pipeline are exercised by 180+ tests (` npm test ` ):
4071
41- - ** DAP protocol tests** drive the real adapter (capability, entry stop, forward
42- and reverse stepping, locals/stack, run-to-breakpoint + reverse-continue).
72+ - ** DAP protocol tests** drive the real adapter (capabilities, entry stop,
73+ forward and reverse stepping at both granularities, locals/stack, Rust source
74+ breakpoints with forward slide, run-to-breakpoint + reverse-continue,
75+ disassembly windows, instruction breakpoints, breakpoint locations).
76+ - ** DWARF tests** decode the committed debug build of ` examples/adder `
77+ (` test/fixtures/adder-debug.wasm ` ) and pin the ` a + b ` line mapping against
78+ its ** matched real trace** (` adder-debug.trace.jsonl ` ); regenerate the pair
79+ together with ` scripts/make-fixtures.sh ` .
4380- ** tx-builder tests** decode every built envelope back with the SDK; envelopes
4481 are additionally cross-checked against the Stellar CLI's own XDR decoder.
4582- ** pipeline tests** run ` TurnkeyPipeline ` against an in-process mock komet-node
4683 and assert the full deploy+invoke sequence and the parsed trace.
4784- ** build integration test** (auto-skips without the toolchain) runs a real
4885 ` stellar contract build ` through ` ContractBuilder ` .
86+ - ` scripts/verify-addresses.mjs ` re-derives the address-space ground truth
87+ (komet ` pos ` convention, DWARF address space) against a live komet-node — the
88+ regression tool for the M0 findings above.
4989
5090## Devcontainer toolchain
5191
@@ -63,16 +103,25 @@ in-process in the extension host (`DebugAdapterInlineImplementation`).
63103```
64104extension.ts VSCode glue: config provider + inline adapter factory
65105debugAdapter/
66- SorobanDebugSession DAP handlers (cursor moves + StoppedEvents)
67- TraceModel records, cursor, call-depth, breakpoint navigation
106+ SorobanDebugSession DAP handlers (cursor moves + StoppedEvents, disassembly)
107+ TraceModel records, cursor, call-depth, line + instruction stepping
108+ artifacts.ts wasm bytes -> { mapper, disassembly, validated positions }
68109 backends/
69- RawTraceBackend M1: replay a JSONL trace file
70- LiveBackend M2: turnkey build + spawn + deploy + trace
110+ RawTraceBackend replay a JSONL trace file (+ optional wasmPath for symbols)
111+ LiveBackend turnkey build + spawn + deploy + trace
71112komet/
72- trace.ts JSONL -> TraceRecord[]
113+ trace.ts JSONL -> TraceRecord[] (K-style mnemonics, section-relative pos)
114+ mnemonics.ts K-style instr arrays -> wasm mnemonics ('i64.const 255')
73115 KometClient.ts JSON-RPC client (getHealth/sendTransaction/traceTransaction/...)
74116soroban/scval.ts launch args -> ScVals (@stellar/stellar-sdk)
75- sourcemap/SourceMapper pos <-> displayed line; v1 renders the trace listing
117+ wasm/
118+ sections.ts wasm section walker (offsets, custom-section lookup)
119+ Disassembly.ts static disassembly (wasmparser), code-offset addressed
120+ dwarf/ DWARF v4/v5 .debug_line/.debug_info parser -> LineTable
121+ sourcemap/
122+ SourceMapper the mapping seam the adapter talks to
123+ DwarfSourceMapper trace index / code offset -> Rust file:line (+ breakpoints)
124+ NullSourceMapper no-DWARF fallback (disassembly-only)
76125```
77126
78127All replay logic is free of the ` vscode ` API so it can be unit-tested in plain
@@ -83,28 +132,27 @@ Node. The `vscode`-only glue lives in `extension.ts`.
83132``` bash
84133npm install
85134npm run build # bundle to dist/extension.js (esbuild)
86- npm test # tsc + mocha (27 tests, incl. DAP protocol tests)
135+ npm test # tsc + mocha
87136npm run check-types # tsc --noEmit
88137npm run lint
89138```
90139
91140Press ** F5** (Run Extension) to open an Extension Development Host with the
92141extension loaded. It opens the [ ` examples/ ` ] ( examples/ ) workspace — a
93- self-contained Soroban project with two contracts ( ` adder ` , ` increment ` ) and a
94- captured trace — so there is something real to debug immediately.
142+ self-contained Soroban project with three contracts and captured traces — so
143+ there is something real to debug immediately.
95144
96145Pick a config from the Run and Debug view. Start with ** Soroban: Replay
97- add(4, 3) trace** , which replays the bundled trace so you can step
98- forward/backward, set breakpoints on instructions, and inspect the stack/locals
99- — end to end, with no komet-node required. The ** Debug add(1, 2)** and ** Debug
100- increment(5)** configs exercise the full build → deploy → trace pipeline.
146+ add(4, 3) with symbols** , which replays the bundled trace * with* the matching
147+ debug wasm: frames land in ` adder/src/lib.rs ` , breakpoints work on Rust lines,
148+ and the Disassembly View shows annotated wasm — no komet-node required. The
149+ ** Debug add(1, 2)** and ** Debug increment(5)** configs exercise the full
150+ build → deploy → trace pipeline.
101151
102152See [ ` examples/README.md ` ] ( examples/README.md ) for details.
103153
104154## Roadmap
105155
106- - ** M3 — Richer time travel:** call-stack reconstruction from call/return depth.
107- - ** M4 — WAT source view:** disassemble the wasm code section and map ` pos ` to
108- WAT lines for breakpoints on real instructions.
109- - ** M5 — DWARF -> Rust source:** map ` pos ` to Rust ` file:line ` using embedded
110- DWARF, for source-level stepping.
156+ - ** M3 — Richer time travel:** call-stack reconstruction from call/return depth
157+ (multi-frame stack traces, frame-scoped locals).
158+ - Column-level breakpoints and inline ` values ` from DWARF variable info.
0 commit comments