Date: 2026-03-31
This repo is not a wreck, but it is absolutely overstated. It compiles, it opens a GUI window, and it has the beginning of a usable LLDB adapter. It is not yet a reliable tracer/debugger.
cargo check: passes after installing a Rust toolchain on this machinecargo test: passes with real LLDB integration coverage against compiled C and C++ fixtures, not just parser/unit testscargo run -p tra86-app: launches the desktop app- the LLDB path can launch, attach, inspect registers/memory/frames, resolve symbols/source, and step real native binaries
tra86-app: real eframe/egui shell with a backend worker threadtra86-backend-lldb: real LLDB process adapter, but text-protocol brittletra86-backend: real trait surface and a thin backend wrappertra86-core: real normalized model types, although broader than the code actually usestra86-ui: real rendering code, but mostly a monolithic panel module rather than a reusable UI library
- “Reliable tracing MVP”: false today
- “Backend-agnostic architecture”: only partially true; the type split exists, but the real behavior is almost entirely LLDB-specific
- “Trace analysis layer”: technically present, but currently a handful of mnemonic heuristics
- “Capability model”: not a real model, just
BTreeMap<String, bool>
BackendOrchestratoradds almost no value beyond owningBox<dyn DebugBackend>.DebugSessionis not driving the app. It looks central in the README and irrelevant in actual runtime flow.Watchpointexists in the core model but has no real pipeline behind it.capabilities()returningBTreeMap<String, bool>is architecture theater, not a durable interface.- The mock backend is useful for UI bring-up, but it currently makes the app look more complete than the real backend path is.
egui_dockis declared but not used.
- LLDB register reads are architecture-fragile. The current explicit register request is x86-heavy and behaved badly on arm64 during this audit.
- Mid-run pause/stop on the current LLDB CLI transport is still not reliable enough to present as done.
- Backend snapshot collection silently converts many backend failures into empty vectors. That keeps the UI alive but hides real faults and desynchronization.
- Trace deduplication is keyed only by instruction address, which can collapse repeated visits to the same IP into misleading history.
- Argument parsing is
split_whitespace(), which breaks quoting and escaped arguments. - The UI can call
std::process::exit(0)directly, which is an ugly shutdown path for a stateful tool.
- Snapshot refreshes fetch a lot of data eagerly and repeatedly.
- Disassembly fetches are large by default and not obviously bounded by user need.
- Trace history is cloned into UI state on every update.
- There is no cache invalidation discipline for disassembly, memory, or symbols.
- There is no profiling or measurement in the repo today.
- The dedicated worker thread is the right direction.
- Session lifecycle handling exists now, but it is still not a full state machine with generation tracking, so process exit/detach/error paths can still leave stale UI state behind.
- Commands are serialized, but there is no cancellation or generation tracking. A slow backend reply can still arrive after the user has changed direction.
- Error handling is inconsistent: command failures sometimes surface, data-fetch failures often disappear.
- The backend trait mixes control, querying, symbol lookup, memory, and disassembly with no typed capability discipline.
- LLDB parsing is line-oriented and heuristic-heavy. It will break on output variation.
- The adapter logs almost nothing structured about command/response flow, which makes backend bugs hard to diagnose.
- Backend-native assumptions still leak upward in practice through incomplete normalization and fallback behavior.
- Six crates for a codebase this small is only justified if the boundaries stay honest. Right now several boundaries are mostly conceptual.
- The capability map is more abstraction than substance.
- The README describes a larger product than the implementation currently supports.
- No real session lifecycle/state machine
- No typed backend capability or failure taxonomy beyond generic backend errors
- No integration tests against real debuggable binaries
- No bounded trace/history policy beyond ad hoc truncation
- No structured backend logging
- No performance measurement framework
- Stop lying in docs and packaging.
- Move off the brittle LLDB CLI command transport for true async control, or explicitly scope the MVP around what the CLI path can do reliably.
- Fix LLDB register/disassembly/frame parsing on current target architectures.
- Stop swallowing backend refresh failures; surface them explicitly in UI state and logs.
- Tighten the session lifecycle model so exit/detach/crash do not leave stale data onscreen.
- Tighten trace/history handling so repeated stepping does not generate misleading state.
- Only after the backend is trustworthy, spend time on layout and UX refinement.
- Make
cargo run -p tra86-appwork without extra binary flags - Add meaningful tests; zero-test green builds are not useful
- Harden LLDB register parsing on arm64 and x86_64
- Replace silent snapshot failure paths with diagnosable errors
- Verify launch, step, disassembly, registers, frames, memory, and breakpoints on a real fixture binary
- Introduce explicit session lifecycle handling in the app worker
- Improve launch/attach behavior so the initial stop is useful
- Add robust error display in the GUI
- Improve argument handling and path validation
- Add structured backend command/response logging
- Bound refresh work and reduce obviously redundant backend calls
- Cache disassembly/symbol/memory data with clear invalidation rules
- Improve register diffing and trace model quality
- Add attach-focused tests and exit/crash-path tests
- Remove or quarantine abstractions that still overpromise capability
- Stronger source correlation
- Better keyboard and navigation UX
- Better visual treatment for large traces and memory views
- Future backend prep once the LLDB path is actually dependable