Connecting to FIDL protocols within components is a combination of capability routing and directory serving. This means that diagnosing connection issues can cover a few different layers:
In this section, you'll explore some APIs and tools to help you find and fix problems with component connections, and monitor the long-term health of your components.
The ffx scrutiny
utility provides a host of features for auditing system security, including an audit of the capability routes in the static component topology. The verify routes
subcommand discovers and reports routing errors, which can help you find any missing offer
or expose
declarations in your manifest.
ffx scrutiny verify routes
This enables you to perform initial validation of your declarations before you even run the components!
[ { "capability_type": "protocol", "results": { "errors": [ { "capability": "fidl.examples.echo.Echo", "error": "no offer declaration for `/core` with name `fidl.examples.echo.Echo`", "using_node": "/core/echo_client" } ] } } ]
The fidlcat
tool allows you to monitor and debug FIDL connections to trace individual FIDL messages sent and received by your component. Similar to the Fuchsia debugger (zxdb
), fidlcat
connects to a running debug_agent
component on the target device and monitors running processes.
![Diagram showing how “fidlcat” interacts with the debug_agent service running on a Fuchsia device to monitor and debug FIDL calls for a given process.] (images/fidlcat.png){: width=“592”}
Setting up the monitoring session requires the following high-level steps:
debug_agent
component on the target device.fidlcat
client and connect to the target device.The simplest method to start a debug session is to use the fx fidlcat
command, which does all of these in the context of your local Fuchsia build. However, these steps can also be performed manually if you need to configure them separately.
Below is an example fidlcat
message for a FIDL protocol request. The trace output contains helpful information for each translation, including:
echo-client.cm 256109:256122 zx_channel_read(handle:handle: e4c7c57f, options:uint32: 0, num_bytes:uint32: 48, num_handles:uint32: 0) -> ZX_OK received response fidl.examples.echo/Echo.EchoString = { response: string = "hello world!" }
Note: For complete details on fidlcat
usage and options, see Monitor and debug your FIDL calls.
Component Inspection enables Fuchsia components to expose structured diagnostic information about themselves using the Inspect API. Fuchsia provides this information through the developer tools and bug reports to assist in diagnosing issues or monitoring performance.
Components expose inspection metrics as a tree of named Nodes, each containing a set of Properties as key/value pairs. Properties support a variety of numeric, string, and array data types. The component inspector libraries provide an interface to your component's root node where you can attach additional properties of interest to your application.
{: width=“583”}
You can retrieve the current set of metrics published to Inspect using the developer tools:
ffx inspect
: Lets you interactively query the Inspect state using component selectors. This is helpful for debugging components during development.ffx target snapshot
: Captures a debug snapshot archive of the entire system, which contains the Inspect data in JSON format.ffx inspect show core/foo-example
core/foo-example: metadata: filename = fuchsia.inspect.Tree component_url = fuchsia-pkg://fuchsia.com/foo-example#meta/foo-example.cm timestamp = 55457379176 payload: root: version = 1.0 request_metrics: request_count = 3 error = timeout
Note: For more details on using the Inspect API, see Fuchsia component inspection.
In this section, you'll use the diagnostics tools to monitor the health and behavior of the echo server component.
You can use fidlcat
to monitor and debug the FIDL connections in your components. Launch fidlcat
and configure it to monitor the echo server component:
fx fidlcat --remote-name=echo_server.cm
Checking for debug agent on [fe80::d6c5:4526:c282:fb6%qemu]:2345. Debug agent not found. Starting one. INFO: [main.cc(238)] Connected to symbol server gs://fuchsia-artifacts-release/debug INFO: [main.cc(122)] Connecting to port 2345 on fe80::d6c5:4526:c282:fb6%qemu... INFO: [main.cc(92)] Connected!
Initiate a FIDL connection to the server by starting an echo client instance:
ffx component bind /core/ffx-laboratory:echo-realm/echo_client
The client binds to the server component and communicates using the Echo
FIDL protocol. Review the fidlcat
output to see a list of the FIDL transactions handled by echo server:
Monitoring echo_server.cm echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = fb9b5273, options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4) -> ZX_OK received request fuchsia.io/Directory.Open = { flags: uint32 = 3, mode: uint32 = 493, path: string = "svc/fidl.examples.routing.echo.Echo", object: handle = Channel:f93b597b(ZX_RIGHT_TRANSFER | ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_SIGNAL | ZX_RIGHT_SIGNAL_PEER | ZX_RIGHT_WAIT | ZX_RIGHT_INSPECT)(channel:0:svc/fidl.examples.routing.echo.Echo) } echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = Channel:f93b597b(channel:0:svc/fidl.examples.routing.echo.Echo), options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4) -> ZX_OK received request fidl.examples.routing.echo/Echo.EchoString = { value: string = "Hello, Fuchsia" } echo_server.cm 58694:58696 zx_channel_write_etc(handle: handle = Channel:f93b597b(channel:0:svc/fidl.examples.routing.echo.Echo), options: uint32 = 0) sent response fidl.examples.routing.echo/Echo.EchoString = { response: string = "Hello, Fuchsia" } -> ZX_OK echo_server.cm 58694:58696 zx_channel_read_etc(handle: handle = Channel:f93b597b(channel:0:svc/fidl.examples.routing.echo.Echo), options: uint32 = 0, num_bytes: uint32 = 512, num_handles: uint32 = 4) -> ZX_ERR_PEER_CLOSED echo_server.cm 58694:58696 zx_handle_close(handle: handle = Channel:f93b597b(channel:0:svc/fidl.examples.routing.echo.Echo)) -> ZX_OK
Notice the sequence of events:
svc/fidl.examples.routing.echo.Echo
.Echo.EchoString
request over the open channel, containing the string payload sent by the client.By tracing the FIDL connections between your components, fidlcat
enables you to find and diagnose potential issues such as failed connections or invalid data payloads.
Component inspection allows you to publish diagnostic information from your components to assist in debugging. You'll use the Inspect API to track some usage statistics for the echo server component.
Update the handle_echo_request()
handler function in main.rs
to accept a new struct containing numeric Inspect properties for request count and bytes processed. The handler increments these properties on each incoming request:
echo-server/src/main.rs
:
// Inspect properties managed by the server struct EchoConnectionStats { total_requests: fuchsia_inspect::UintProperty, bytes_processed: fuchsia_inspect::UintProperty, } // Handler for incoming service requests async fn handle_echo_request(mut stream: EchoRequestStream, stats: &EchoConnectionStats) { while let Some(event) = stream.try_next().await.expect("failed to serve echo service") { let EchoRequest::EchoString { value, responder } = event; responder.send(value.as_ref().map(|s| &**s)).expect("failed to send echo response"); if let Some(message) = value { // Update Inspect property values stats.total_requests.add(1); stats.bytes_processed.add(message.len() as u64); } } }
Add the following code to main()
to initialize the Inspect propertes and pass them to the updated handler:
echo-server/src/main.rs
:
async fn main() -> Result<(), anyhow::Error> { // ... // Component is serving and ready to handle incoming requests component::health().set_ok(); {{ '<strong>' }}// Create request tracking properties {{ '</strong>' }} {{ '<strong>' }}let root_node = component::inspector().root(); {{ '</strong>' }} {{ '<strong>' }}let stats = EchoConnectionStats { {{ '</strong>' }} {{ '<strong>' }}total_requests: root_node.create_uint("total_requests", 0), {{ '</strong>' }} {{ '<strong>' }}bytes_processed: root_node.create_uint("bytes_processed", 0), {{ '</strong>' }} {{ '<strong>' }}}; {{ '</strong>' }} // Attach request handler for incoming requests service_fs .for_each_concurrent(None, |_request: IncomingRequest| async { match _request { {{ '<strong>' }}IncomingRequest::Echo(stream) => handle_echo_request(stream, &stats).await, {{ '</strong>' }} } }) .await; Ok(()) }
Finally, update the imports in main.rs
to include the new Inspect libraries:
echo-server/src/main.rs
:
use anyhow::{self, Context}; use fidl_fidl_examples_routing_echo::{EchoRequest, EchoRequestStream}; use fuchsia_component::server::ServiceFs; use fuchsia_inspect::{component, health::Reporter}; use fuchsia_inspect::NumericProperty; use futures::prelude::*;
Run fx build
again to rebuild the component:
fx build
Stop the current echo-server
component instance. This allows the component to resolve the latest version from the package server the next time it starts.
ffx component stop /core/ffx-laboratory:echo-realm/echo_server
Run the echo client component multiple times. This causes the request count in echo-server
to increment with each connection:
ffx component bind /core/ffx-laboratory:echo-realm/echo_client ffx component bind /core/ffx-laboratory:echo-realm/echo_client ffx component bind /core/ffx-laboratory:echo-realm/echo_client
View the available Inspect data for the echo server component with ffx inspect
. You'll see the values for request count and bytes processed in the tree under the root
node alongside the component health status:
ffx inspect show 'core/ffx-laboratory\:echo-realm/echo_server'
core/ffx-laboratory\:echo-realm/echo_server: metadata: filename = fuchsia.inspect.Tree component_url = #meta/echo_server.cm timestamp = 1476246046122 payload: root: bytes_processed = 42 total_requests = 3 fuchsia.inspect.Health: start_timestamp_nanos = 1467828507317 status = OK
Publishing health and behavior information using Inspect enables you to observe the current state of your components and diagnose issues on production devices.
Congratulations! You've successfully built a Fuchsia IPC interface using FIDL, and connected two components together using that interface.
You have completed all the modules in this course! Take your newfound understanding to the next level and dive deeper into the:
Fuchsia concepts