启动 fidlcat 并附加到正在运行的进程后,该工具会开始记录使用 FIDL 发送和接收的系统调用。
请参阅以下来自 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))
示例输出包含以下信息:
echo_client.cm:生成相应显示内容的进程的名称。
193974:进程 koid。
193976:线程 koid。
zx_channel_create:拦截/显示的系统调用的名称。
按名称、类型和值列出的系统调用输入参数(例如 handle 和 options)。
系统调用返回值 (
ZX_OK) 和输出参数。
对于表示 FIDL 交易的系统调用,fidlcat 会显示额外的输入和输出参数。请参阅以下同步 fuchsia.examples/Echo.EchoString 请求示例:
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" }
请注意显示输出中的 FIDL 请求和响应消息,包括方法名称和参数。
修改显示内容
默认情况下,fidlcat 仅在每条消息的第一行显示进程信息。使用 --with-process-info 标志可在每行中添加以下详细信息:
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 标志,您可以显示每个系统调用的堆栈帧。默认情况下 (--stack=0),系统不会显示堆栈帧。
使用 --stack=1 时,仅显示调用位置(1 到 4 个帧):
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" }
此选项不会增加任何开销(显示屏除外)。
使用 --stack=2 时,系统会显示所有帧:
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" }
此选项会增加一些开销,因为我们需要针对每个系统调用向 zxdb 请求完整的堆栈(并且 fidlcat 会变得更加冗长)。只有在需要了解代码的哪个部分调用了系统调用时,才应使用此功能。
过滤输出
系统调用
默认情况下,fidlcat 仅显示 zx_channel 系统调用。
借助 --syscalls 选项,您可以定义一个正则表达式,用于选择要解码和显示的系统调用。
如需显示所有系统调用,请使用:--syscalls=".\*"
--exclude-syscalls 标志定义了一个正则表达式,用于从 --syscalls 选择的 syscall 集中排除 syscall。
若要显示系统调用,该系统调用必须满足 --syscalls 模式,但不满足 --exclude-syscalls 模式。
以下示例显示了所有系统调用,但 zx_handle 除外:
--syscalls ".\*" --exclude-syscalls "zx_handle_.\*"
信息
默认情况下,fidlcat 会显示所有消息。
您可以使用以下方式指定要显示的讯息:
借助
--messages,您可以指定消息必须满足的一个或多个正则表达式才能显示。借助
--exclude-messages,您可以指定一个或多个正则表达式,消息必须不满足这些表达式才能显示。
如果同时使用这两个选项,则要显示的消息必须满足 --messages 指定的某个正则表达式,并且不满足 --exclude-messages 指定的任何正则表达式。
消息过滤功能适用于方法的完全限定名称。例如,以下标志:
--messages=".*Open"
匹配如下方法:
fuchsia.io/Directory.Open
fuchsia.io/Node.OnOpen
线程
使用 --thread=<thread koid> 选项时,系统只会显示指定线程中的事件。此选项可多次使用,以显示多个线程。
分组输出
协议
使用 --with=top 和 --with=top=<path> 选项生成按进程、协议和方法分组输出的视图。这些群组按事件数量排序,因此关联的事件较多的群组会列在前面。
线程
使用 --with=group-by-thread 和 --with=group-by-thread=<path> 选项可生成一个视图,其中显示每个线程的所有事件的简短版本。
推迟显示消息
默认情况下,fidlcat 在附加到进程后立即开始显示消息。
您可以使用 --trigger 选项来延迟显示,直到提供的正则表达式与收到的消息匹配为止。
当您需要了解在收到或发出特定消息后会发生什么时,此功能非常有用。
摘要视图
如需将 fidlcat 配置为显示会话的高级摘要,而不是列出各个消息,请使用选项 --with=summary 和 --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
此命令会显示会话中所有受监控的进程、句柄和渠道的列表,以及其他摘要详细信息:
句柄:句柄是启动句柄(在进程创建期间继承)还是在进程生命周期内创建的。 对于非启动句柄,
fidlcat还会显示有关用于创建和关闭每个句柄的系统调用的信息。渠道:显示负责渠道另一端的句柄以及已发送和接收的 FIDL 消息列表。
持续监控
默认情况下,当所有附加的进程退出时,fidlcat 会话会终止。
使用 --stay-alive 选项可让会话一直运行,直到您手动退出 fidlcat(例如,使用 Ctrl-C)。
这样,您就可以在同一监控会话中多次重启程序。每次重新启动时,fidlcat 会话都会自动附加到新进程。