v0.8: step-over (next/trace), symbol demangling, disasm len/is_call, ergonomics

Driven by the friction the v0.7 smarm session hit: single-stepping the
context-switch shim dove into every helper call, and every step needed
`nm | grep` for a mangled name whose hash changes each rebuild. This round
makes tracing the shim pleasant.

Rust (kept minimal — only what JS genuinely can't do):
- symbols.rs: demangle Rust symbols. addr("name") now resolves by exact
  mangled/case-insensitive (unchanged), then by full demangled path
  (smarm::context::switch_to_scheduler), then by *unique* final path
  component (switch_to_scheduler). Ambiguous short names resolve to None and
  bp.set reports "matches N symbols" rather than guessing. sym()/name_for_addr
  return demangled names so traces are readable. Adds rustc-demangle dep.
- disasm.rs: Decoded gains `len` (instruction byte length) and `is_call`
  (iced FlowControl::Call, incl. indirect). js.rs exposes both on disasm
  records so step-over finds the return address without re-parsing text.

Prelude (everything else, like until/finish):
- next(n): step OVER calls — one-shot bp at pc+len, cont, cleanup; else
  single-step. A stepped-over call fires the `step` listener once. Detects
  calls that don't return to pc+len (stack-switching shims, longjmp): on a
  non-matching stop it dispatches the real event and stops instead of hanging.
- trace(from, to, {over, range, capture, print, max}): run-to-A then
  step(-over)-to-B with per-step capture; `range:[lo,hi]` stops when pc leaves
  a range. Drives the native steppers directly (no listener coupling).
- watch(specs): a `step` listener printing named expressions each step.
- fmt(): BigInt-safe stringify. state.insn: disasm record at pc.
  stackContains/stackDistance/region: stack-region legibility for cross-stack
  handoffs. step(n, {summary}): first/last/count for large N.

Docs: README status row + prelude reference + sections on the next() caveat,
the conditional-breakpoint listener idiom, and BigInt ergonomics.
examples/smarm_ctx_switch_next.js traces a full switch_to_scheduler in 16
readable lines using trace({over:true}).

No-listener fast paths and the v0.7 example are unaffected (verified).
This commit is contained in:
llmdbg-dev
2026-05-28 06:20:43 +00:00
parent ce96a98829
commit f0698573cd
8 changed files with 569 additions and 18 deletions
Generated
+7
View File
@@ -95,6 +95,7 @@ dependencies = [
"nix",
"object",
"rquickjs",
"rustc-demangle",
]
[[package]]
@@ -180,6 +181,12 @@ dependencies = [
"cc",
]
[[package]]
name = "rustc-demangle"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
[[package]]
name = "serde"
version = "1.0.228"