Skip to content

docs: rewrite quickstart and add runtimes/system drivers structure#3

Merged
NathanFlurry merged 1 commit into
mainfrom
docs-quickstart-rewrite
Mar 10, 2026
Merged

docs: rewrite quickstart and add runtimes/system drivers structure#3
NathanFlurry merged 1 commit into
mainfrom
docs-quickstart-rewrite

Conversation

@NathanFlurry

Copy link
Copy Markdown
Member

Restructure documentation with new conceptual architecture:

  • Rewrote quickstart with tabs for Node vs Browser setup
  • Added complete API reference page listing all exports and types
  • Introduced Runtimes group with overview, Node, and Python pages
  • Introduced System Drivers group with overview, Node, and Browser pages
  • Each runtime/driver page provides conceptual overview with illustrative code snippets
  • Updated CLAUDE.md with documentation maintenance checklist

@NathanFlurry NathanFlurry merged commit 1c92d78 into main Mar 10, 2026
1 check passed
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
… the real blocker

The net.poll_wait TCB fix (signed off) is implemented and verified, but the render is still
blocked by a SEPARATE livelock: 3 guest VMs spin in wasm during the first GTK draw dispatch (not
in the poll path), independent of poll ceiling. Next step is tool #3 (wasm-level stack symbolizer)
to name the spinning function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…8.1)

The native backtrace stops at the V8 C++/JIT boundary and the interrupt callback cannot open a
HandleScope, so a livelocked wasm spin was unnameable. This names it WITHOUT a scope:
- SetJitCodeEventHandler (pure-C ABI, called straight from Rust via the mangled symbol in
  librusty_v8.a; no C++ shim) records every JIT code blob range+name as V8 compiles it. V8 names
  wasm frames wasm-function[N]-N-liftoff and JS frames with file:line.
- At the interrupt safepoint we run ON the spinning thread, so a conservative scan of this threads
  own stack (bounded by pthread_attr_getstack) for return addresses landing in a recorded range
  reveals the live call chain, innermost-first.
Installed on both the fresh-isolate and snapshot-restore paths; gated on SECURE_EXEC_STACKDUMP_AFTER_MS
(zero cost otherwise). Only the JitCodeEvent ABI prefix + the name union arm are read (matches v8 130).

First use cracked the M8.4 render diagnosis: all 3 guest VMs are stuck in
net_poll -> callSyncRpc -> callSync (the poll/sync-RPC path), NOT in GTK draw as previously
hypothesized. Reframes the blocker as a cross-VM poll/sync-RPC deadlock.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
… render diagnosis

Tool #2 (X11 wire tap + xdecode.py) and tool #3 (wasm-frame symbolizer for livelocked guests) are
committed and cracked the render diagnosis: both guests spin in net_poll, data delivery is complete,
the X server sits idle in WaitForSomething without replying to a delivered first-draw RENDER request.
The earlier prediction that C names survive the build was wrong (fpcast-emu + -Oz strip them) — which
is exactly why tool #3 was needed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…er root to an unknown ext opcode

- scripts/xreassemble.py: reassembles the FULL client/server X11 byte streams (handling the setup
  request/reply + BigRequests) and matches requests to replies by sequence, so the exact unanswered
  request is visible. SECURE_EXEC_XTRACE=<n> now sets the per-payload capture cap (default 256; large
  for full reassembly).
- ActiveUnixSocket::poll: try_recv first, so a guest non-blocking drain (net.poll(fd,0)) never misses a
  delivered request via the recv_timeout(ZERO)-returns-Timeout-with-data-pending std gotcha. Strictly
  more correct (did not by itself unblock the render).

DIAGNOSIS (tools #2/#3): lxpanel creates the panel toplevel + sets its DOCK/_NET_WM properties but the
toplevel is NEVER mapped — GTK queued its MapWindow in the GLib loop, which is stuck in its first
dispatch. lxpanel waits for a GetInputFocus reply (op 0x2b) that never arrives; the server received all
bytes (delivery is byte-symmetric) yet sits idle in net_poll. Root lead: the first-draw batch sends
requests with major opcode 0x89=137, but Xvfb's registered extensions use opcodes 128/130/132/134/138 —
NO extension owns 137. An unknown-opcode request mis-handled by the server desyncs the request stream
(server waits for bytes to finish a phantom request; client waits for its reply) = the deadlock. Next:
confirm which client lib emits op 137 / fix Xvfb's unknown-opcode handling (platform layer).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NathanFlurry added a commit that referenced this pull request Jul 1, 2026
…sync-RPC throughput

Measured it instead of asserting. Added a dispatch busy-fraction metric to the M8.1 watchdog
(busy_us/wall) + a CPU sampler. Evidence that overturns the throughput theory:
- sidecar DISPATCH THREAD is 99% IDLE (busy~0.5%, mean 12-38us/op) - NOT serialization-bound.
- yet the sidecar pegs 100-140% CPU continuously; thread count climbs to ~114.
- bring-up has multi-second gaps (one was 32s) where dispatch op-count is FROZEN but CPU pegged.
- M8.1 stackdump on a guest during a gap: a thread RUNNING (JIT/wasm), NOT parked on a futex, with
  a byte-for-byte identical stack across 600ms samples (wasm-function[13130]+0x3d) = a CPU busy-SPIN.
- the spinning guest is pcmanfm (26907 funcs; stack references func index 26531).

So it's a guest-side livelock/busy-wait (a sync primitive spinning instead of memory.atomic.wait-
parking, likely a spinning lock-holder since ALL guests stall when one spins), not a throughput/
serialization problem and not a clean deadlock. Earlier "parallelize sync-RPC" conclusion was a
mis-diagnosis - the dispatch is idle. SPEC corrected + acceptance bar made explicit (a black/empty
framebuffer is NOT acceptance; the deliverable is the rendered desktop). Identifying the exact spin
is blocked on symbolizing fpcast'd wasm (no name section, DWARF low_pc all 0, symtab stripped) -
the M8.1 tool #3-bis.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant