Honoring Asian Pacific American Heritage Month. See how.

fidlcat: Guide

Once you have launched fidlcat and attached to a running process, the tool begins logging system calls sent and received using FIDL.

See the following basic example output from fidlcat:

Monitoring echo_client.cm koid=193974

echo_client.cm 193974:193976 zx_channel_create(options: uint32 = 0)
  -> ZX_OK (out0: handle = d7e9f83b(channel:0), out1: handle = d6c9fd5f(channel:1))

The example output contains the following information:

  • echo_client.cm: the name of the process that has generated this display.

  • 193974: the process koid.

  • 193976: the thread koid.

  • zx_channel_create: the name of the intercepted/displayed system call.

  • system call input parameters (such as handle and options) listed by name, type, and value.

  • system call return value (ZX_OK) and output parameters.

For system calls representing a FIDL transaction, fidlcat displays additional input and output parameters. See the following example of a synchronous fuchsia.examples/Echo.EchoString request:

echo_client.cm 193974:193976 zx_channel_call_etc(handle: handle = Channel:d089f8fb(dir:/svc/fuchsia.examples.Echo), options: uint32 = ZX_CHANNEL_WRITE_USE_IOVEC, deadline: zx.time = ZX_TIME_INFINITE, rd_num_bytes: uint32 = 64, rd_num_handles: uint32 = 64)
  sent request fuchsia.examples/Echo.EchoString = { value: string = "hello" }
  -> ZX_OK
    received response fuchsia.examples/Echo.EchoString = { response: string = "hello" }

Notice the FIDL request and response messages in the display output, including the method name and parameters.

Modifying the display

By default, fidlcat only displays process information on the first line of each message. Use the flag --with-process-info to include these details on each line:

echo_client.cm 60014:60016 zx_channel_call_etc(handle: handle = Channel:35272afb(dir:/svc/fuchsia.examples.Echo), options: uint32 = ZX_CHANNEL_WRITE_USE_IOVEC, deadline: zx.time = ZX_TIME_INFINITE, rd_num_bytes: uint32 = 64, rd_num_handles: uint32 = 64)
echo_client.cm 60014:60016   sent request fuchsia.examples/Echo.EchoString = { value: string = "hello" }
echo_client.cm 60014:60016   -> ZX_OK
echo_client.cm 60014:60016     received response fuchsia.examples/Echo.EchoString = { response: string = "hello" }

Stack frames

Using the flag --stack you can display the stack frames for every system call. By default (--stack=0), the stack frames are not displayed.

With --stack=1 only the call site (1 to 4 frames) is displayed:

echo_client.cm 675407:675409 at zircon/system/ulib/fidl/llcpp_message.cc:243:12 fidl::OutgoingMessage::CallImpl
echo_client.cm 675407:675409 zx_channel_call_etc(handle: handle = Channel:8b745347(dir:/svc/fuchsia.examples.Echo), options: uint32 = ZX_CHANNEL_WRITE_USE_IOVEC, deadline: zx.time = ZX_TIME_INFINITE, rd_num_bytes: uint32 = 64, rd_num_handles: uint32 = 64)
  sent request fuchsia.examples/Echo.EchoString = { value: string = "hello" }
  -> ZX_OK
    received response fuchsia.examples/Echo.EchoString = { response: string = "hello" }

This option doesn't add any overhead (except for the display).

With --stack=2 all the frames are displayed:

echo_client.cm 717533:717535 at 3ac285b4811 _start
echo_client.cm 717533:717535 at zircon/third_party/ulib/musl/src/env/__libc_start_main.c:215:5 __libc_start_main
echo_client.cm 717533:717535 at zircon/third_party/ulib/musl/src/env/__libc_start_main.c:140:3 start_main
echo_client.cm 717533:717535 at examples/fidl/llcpp/client_sync/main.cc:30:27 main
echo_client.cm 717533:717535 at fidling/gen/examples/fidl/fuchsia.examples/fuchsia.examples/llcpp/fidl/fuchsia.examples/cpp/wire_messaging.h:2711:12 fidl::internal::WireSyncClientImpl<fuchsia_examples::Echo>::EchoString
echo_client.cm 717533:717535 at fidling/gen/examples/fidl/fuchsia.examples/fuchsia.examples/llcpp/fidl/fuchsia.examples/cpp/wire_messaging.cc:1051:12 fidl::WireResult<fuchsia_examples::Echo::EchoString>::WireResult
echo_client.cm 717533:717535 at zircon/system/ulib/fidl/include/lib/fidl/llcpp/message.h:205:3 fidl::OutgoingMessage::Call<fidl::WireResponse<fuchsia_examples::Echo::EchoString>, zx::unowned<zx::channel> >
echo_client.cm 717533:717535 at zircon/system/ulib/fidl/include/lib/fidl/llcpp/message.h:196:5 fidl::OutgoingMessage::Call<fidl::WireResponse<fuchsia_examples::Echo::EchoString> >
echo_client.cm 717533:717535 at zircon/system/ulib/fidl/llcpp_message.cc:243:12 fidl::OutgoingMessage::CallImpl
echo_client.cm 717533:717535 zx_channel_call_etc(handle: handle = Channel:f751d2fb(dir:/svc/fuchsia.examples.Echo), options: uint32 = ZX_CHANNEL_WRITE_USE_IOVEC, deadline: zx.time = ZX_TIME_INFINITE, rd_num_bytes: uint32 = 64, rd_num_handles: uint32 = 64)
  sent request fuchsia.examples/Echo.EchoString = { value: string = "hello" }
  -> ZX_OK
    received response fuchsia.examples/Echo.EchoString = { response: string = "hello" }

This option adds some overhead because we need to ask zxdb for the full stack for each system call (and fidlcat becomes even more verbose). You should use it only when you need to understand what part of your code called the system calls.

Filtering output

Syscalls

By default, fidlcat only displays zx_channel syscalls. The --syscalls option allows you to define a regular expression that selects the syscalls to decode and display.

To display all the syscalls, use: --syscalls=".\*"

The --exclude-syscalls flag defines a regular expreission that excludes syscalls from the set selected by --syscalls.

To be displayed, a syscall must satisfy the --syscalls pattern and not satisfy the --exclude-syscalls pattern.

The following example displays all syscalls, except for zx_handle:

--syscalls ".\*" --exclude-syscalls "zx_handle_.\*"

Messages

By default, fidlcat displays all the messages. You can specify the messages you want to display using:

  • --messages allows you to specify one or more regular expressions the messages must satisfy to be displayed.

  • --exclude-messages allows you to specify one or more regular expressions the messages must not satisfy to be displayed.

If both options are used at the same time, to be displayed, a message must satisfy one of the regular expressions specified with --messages and not satisfy any regular expression specified with --exclude-messages.

Message filtering works on the method's fully qualified name. For example, the following flag:

--messages=".*Open"

Matches methods like:

fuchsia.io/Directory.Open
fuchsia.io/Node.OnOpen

Threads

When using the option --thread=<thread koid> only the events from the specified thread are displayed. The option can be used several times to display several threads.

Grouping output

Protocols

Use the options --with=top and --with=top=<path> to generate a view that groups the output by process, protocol, and method. The groups are sorted by number of events, so groups with more associated events are listed earlier.

Threads

Use the options --with=group-by-thread and --with=group-by-thread=<path> to generate a view that displays a short version of all the events for each thread.

Postponing the message display

By default, fidlcat begins displaying messages immediately after it attaches to the process.

You can use the --trigger option to defer the display until the provided regular expression matches an incoming message.

This is really useful when you need to understand what's going on after you received or emit a particular message.

Summary view

To configure fidlcat to display a high level summary of the session instead of listing individual messages, use the options --with=summary and --with=summary=<path>.

echo_client.cm 1505832: 16 handles

  Process:ac4ce043(proc-self)

  startup Vmar:a43cfe53(vmar-root)

  startup Thread:d5dce00f(thread-self)

  startup Channel:91cce2f3(dir:/svc)
      write request  fuchsia.io/Directory.Open(".")
        -> Channel:c65ce1c3(dir:/svc)

  startup Channel:daece3fb(dir:/pkg)

  startup Socket:cb8ce31f(fd:1)
    closed by zx_handle_close

  startup Socket:df8ce687(fd:2)
    closed by zx_handle_close

  startup Channel:93ccfcf7(directory-request:/)

  startup Clock:b7ecfe9b()

  startup Job:674ce17f(job-default)

  startup Vmo:adbcfc9f(vdso-vmo)

  startup Vmo:ef2ce06f(stack-vmo)

  Channel:c65ce1c3(dir:/svc)
    linked to Channel:da9cebcb(channel:1)
    created by zx_channel_create
      write request  fuchsia.io/Directory.Open("fuchsia.examples.Echo")
        -> Channel:767ce3f3(dir:/svc/fuchsia.examples.Echo)
    closed by zx_handle_close

  Channel:da9cebcb(channel:1)
    linked to Channel:c65ce1c3(dir:/svc)
    created by zx_channel_create
    closed by Channel:91cce2f3(dir:/svc) sending fuchsia.io/Directory.Open

  Channel:767ce3f3(dir:/svc/fuchsia.examples.Echo)
    linked to Channel:f4bce307(channel:3)
    created by zx_channel_create
      call  request  fuchsia.examples/Echo.EchoString
      write request  fuchsia.examples/Echo.SendString
      read  event    fuchsia.examples/Echo.OnString
    closed by zx_handle_close

  Channel:f4bce307(channel:3)
    linked to Channel:767ce3f3(dir:/svc/fuchsia.examples.Echo)
    created by zx_channel_create
    closed by Channel:c65ce1c3(dir:/svc) sending fuchsia.io/Directory.Open

This displays a list of all the monitored processes, handles, and channels in the session with additional summary details:

  • Handles: Whether the handle is a startup handle (inherited during process creation) or created during the process life. For non-startup handles, fidlcat also displays information about the syscalls used to create and close each handle.

  • Channels: Displays the handle responsible for the other end of the channel and the list of FIDL messages sent and received.

Continuous monitoring

By default, the fidlcat session terminates when all the attached processes exit.

Use the option --stay-alive to keep the session running until you manually exit fidlcat (for example, using Ctrl-C).

This allows you to restart a program multiple times within the same monitoring session. With each restart, the fidlcat session attaches to the new process automatically.