src/developer/debug Development Guide for AI Agents

Follow these cross-cutting rules and progressive-disclosure gates when you write, refactor, or review code under //src/developer/debug.

Subsystem Map & Mandatory README.md Pre-Edit Gate

Each subsystem maintains a local README.md contract with ## Interface, ## Invariants, ## Side Effects, and ## Verification sections.

Mandatory Pre-Edit & Code Review Gate: Before you edit or review (/review) any file in a subdirectory, read ## Invariants and ## Verification in its README.md.

Each subsystem maps to a local contract, build target, test suite, and architectural layer:

  • debug_agent/ (README.md, posix): Target-side Fuchsia and Linux stub (DebugAgent, DebuggedJob, DebuggedProcess, DebuggedThread, LimboProvider). Build //src/developer/debug/debug_agent and run fx test debug_agent_unit_tests.
  • ipc/ (README.md): Versioned binary wire protocol (debug_ipc) between zxdb and debug_agent. Build //src/developer/debug/ipc and run fx test zxdb_tests.
  • shared/ (README.md, logging): Cross-platform MessageLoop, StreamBuffer, BufferedStream, Arch, RegisterID, Status, and Result. Build //src/developer/debug/shared and run fx test zxdb_tests.
  • zxdb/common/ (README.md): Layer 1 (Lowest) base utilities (Err, ErrOr, AddressRanges). Must not depend on other zxdb layers. Build //src/developer/debug/zxdb/common and run fx test zxdb_tests.
  • zxdb/symbols/ (README.md): Layer 2 DWARF and ELF symbol indexing (Index, DwarfDieRef, LazySymbol) and DwarfExprEval. Build //src/developer/debug/zxdb/symbols and run fx test zxdb_tests.
  • zxdb/expr/ (README.md): Layer 3 C++ and Rust parser, AST (ExprNode), bytecode VM (VmExec), and PrettyType. Build //src/developer/debug/zxdb/expr and run fx test zxdb_tests.
  • zxdb/format/ (README.md): Layer 4 styled output buffers (OutputBuffer, AsyncOutputBuffer) and value or identifier formatting. Build //src/developer/debug/zxdb/format and run fx test zxdb_tests.
  • zxdb/client/ (README.md): Layer 4 UI-agnostic session model (Session, Target, Process, Thread, Stack, ThreadController). Build //src/developer/debug/zxdb/client and run fx test zxdb_tests.
  • zxdb/console/ (README.md, commands): Layer 5 (UI) interactive CLI frontend, noun and verb parser, and ConsoleContext. Build //src/developer/debug/zxdb/console and run fx test zxdb_tests.
  • zxdb/debug_adapter/ (README.md, handlers): Layer 6 (UI) cppdap Debug Adapter Protocol (DAP) server sharing client::Session. Build //src/developer/debug/zxdb/debug_adapter and run fx test zxdb_tests.
  • ffx_zxdb/ (README.md, src, ffx/AGENTS.md): Host Rust integration for ffx debug. Read //src/developer/ffx/AGENTS.md for FDomain and fho rules, and build //src/developer/debug/ffx_zxdb.
  • e2e_tests/ (README.md): Host-driven .script E2E tests and dap_integration_tests. Run fx test --e2e zxdb_e2e_tests.

Enforce this upward dependency rule across zxdb/:

  • Strict Upward Layering in zxdb/: Dependencies inside zxdb/ must point upward (common <- symbols <- expr <- {format, client} <- console <- debug_adapter).

Cross-Cutting Idioms

Apply these C++ and subsystem idioms across all files in //src/developer/debug:

  • Async Object Lifetimes: Never capture raw pointers (Target*, Process*, Thread*, Frame*, Breakpoint*, FormatNode*) across asynchronous callbacks. Capture fxl::WeakPtr<T> (or fxl::RefPtr<T> for ref-counted Symbol, EvalContext, CommandContext, AsyncOutputBuffer) and check validity before dereferencing.
  • Lazy Stack & Multi-Thread State: Never assume all stack frames exist when a thread stops (debug_agent sends only the top 1 to 2 frames). Call Stack::SyncFrames asynchronously for full backtraces, and check process->AllThreadsStopped() before inspecting process-wide state.
  • Error Returns vs. Invariant Assertions: Never use bool with out-parameter pointers for fallible parsing or validation. Return zxdb::ErrOr<T> (in zxdb) or debug::Status / debug::Result<T, E> (in shared, ipc, debug_agent). Reserve FX_CHECK and FX_DCHECK for internal programmer invariants.
  • Sentinel Values (0): Never use 0 as an invalid sentinel for DWARF unit offsets or type signatures. 0 is valid in DWARF, so use std::optional<uint64_t>. For Zircon KOIDs (zx_koid_t), 0 (ZX_KOID_INVALID) is invalid, so reject 0 when parsing external or DAP IDs.
  • Callbacks & Symbol RTTI: Never use std::function or C++ dynamic_cast (the build disables compiler RTTI). Use fit::function, fit::callback, or fit::deferred_callback, and call symbol->As<T>() to downcast Symbol objects.
  • Internal Linkage & TODOs: Place file-local .cc helpers in an anonymous namespace. Format bug links as https://fxbug.dev/<id>, and state the condition required to delete each TODO.
  • Agent Skill Encapsulation: Never expose internal ffx debug or zxdb Unix socket paths in skills/ documentation. Direct agents through supported CLI commands instead.

Downstream Couplings, Documentation, & Reviewer Gates

Follow these build, documentation, comment, and testing gates before completing any work:

  • Dual Bazel/GN Build Files (# BAZEL2GN SENTINEL): Never hand-edit BUILD.gn files below a # BAZEL2GN SENTINEL marker. Edit the matching BUILD.bazel file and run fx bazel2gn.
  • Documentation Freshness & Prose Style:
    • Update matching documentation (//docs/development/debugger/, local README.md contracts, and CLI help text in verbs.h / verb_*.cc) whenever you edit user-facing surfaces or internal architecture. Create new documentation if none exists.
    • Keep standalone documentation distinct from code comments. Standalone docs explain the problem, architecture, and high-level approach. Inline code comments explain non-obvious implementation mechanics.
    • Write all non-coding prose in Simplified Technical English (asd-ste100) and follow Google Technical Writing guidelines (technical-writing).
  • Code Comment Style:
    • Never use numbered lists (// 1., // Step 1:) in source code comments. Decompose multi-phase logic into named helper functions and let symbol names show execution order.
    • Prefer longer explanatory block comments with references for complex sequences over short comments scattered through the sequence.
  • Co-locate Unit Tests in Patch Stacks: Include unit tests in the same CL that introduces a new class, data structure, or handler. Never defer unit tests to a later commit in a patch stack.
  • Mandatory Boundary, Control-Flow, & Multi-Thread Coverage:
    • Test zero and invalid boundaries explicitly (CU offset 0, invalid DWARF signatures, koid == 0). Test multi-threaded states with 2 or more threads (such as zxdb.AsyncBacktrace and pause synchronization).
    • In ThreadController subclasses and DebuggedThread exception paths, test early-exit paths (bottom frames, PLT trampolines, unrelated breakpoints). Use fit::defer or fit::deferred_callback to restore state on early returns.
    • Never land commented-out test assertions.
  • Editing & Verification Workflow Skill: Read editing-zxdb to build targets, run unit and E2E tests, reload /core/debugger, and test with fx debug cli.