This tutorial explains the concepts and workflow of agent debugging mode in
fx test and how to manage symbol loading and breakpoint resolution when
integrating with automated scripts or IDE debuggers.
Overview
Agent debugging mode is designed for headless automation, IDE integration (like
VS Code), and scripts. It runs zxdb as a background server exposing a Debug
Adapter Protocol (DAP) endpoint on a Unix domain socket at
/tmp/fx-debug-daemon.sock.
To start a test suite in this mode:
fx test <TEST_SUITE_NAME> --agent-debugging-modeDefault behavior: weak attachment
When you run fx test --agent-debugging-mode without any breakpoint arguments,
the testing framework attaches zxdb to the target process "weakly" (using the
attach --weak command).
What is weak attachment?
Weak attachment optimizes startup performance by preventing zxdb from
proactively querying modules and loading symbol indexes for the process.
- Deferred symbol loading:
zxdbdoes not load symbols upon the initial attach. - Resolution limitations: because the symbol index is missing, any
file:lineor symbolic breakpoints registered dynamically through the DAP UDS interface after the test starts will remain "pending" and cannot be verified or resolved. - Autoresolution on crash: an exception or external event (such as a Rust panic or a C++ assertion failure) triggers symbol loading. Once stopped, symbols load automatically and pending breakpoints resolve.
Solution: proactive breakpoint installation
If you need to debug a passing path, or if you want to ensure your breakpoints
are active and verified before execution starts, you must specify them on the
fx test command line:
fx test <TEST_SUITE_NAME> --agent-debugging-mode --breakpoint <SOURCE_FILE>:<LINE>How it works
- The presence of the
--breakpointoption tells thefxtestframework to attachzxdbnormally (omitting the--weakflag). - Because the attachment is normal,
zxdbimmediately loads symbols for the target process. zxdbinstalls and resolves the specified breakpoints upfront during the initialization handshake.- When the test execution hits the breakpoint, the debugger suspends the
process and sends a
"stopped"event with"reason": "breakpoint"to the DAP client.
Interactive debugging using fx debug cli
Once the execution stops at a breakpoint or exception, you can interact with
the debugger from a second terminal using the fx debug cli wrapper tool.
To connect and retrieve the current debugger state:
fx debug cli --json '{"command": "get-state"}'The tool returns a JSON response listing active processes and threads:
{
"success": true,
"body": {
"threads": [
{ "id": 1, "name": "initial-thread" }
],
"processes": { "12345": "my_test_binary" }
}
}
To retrieve a stack trace for a specific thread, pass the thread_id:
fx debug cli --json '{"command": "stackTrace", "thread_id": 1}'The tool returns the stack frame details:
{
"success": true,
"body": {
"stackFrames": [
{
"id": 0,
"name": "my_test_function",
"source": {
"name": "main_test.cc",
"path": "/src/main_test.cc"
},
"line": 42,
"column": 1
}
],
"totalFrames": 1
}
}
Once diagnostic inspection is complete, resume the execution of the thread:
fx debug cli --json '{"command": "continue", "thread_id": 1}'Use fx debug cli help to get a list of all commands you can run.