fuchsia Zircon Hypervisor:调测手段

本文详细介绍了谷歌Fuchsia操作系统的调试技术,包括Zircon微内核的GDB和Zxdb调试,进程异常退出时的堆栈打印与符号解析,FIDL通信调试,以及syslog系统日志调测。通过GDB调试内核镜像,Zxdb进行程序调试,以及使用fidlcat工具监控FIDL消息,开发者可以深入理解Fuchsia系统的运行机制。此外,文章还提到了trace和syslog工具,用于系统性能分析和日志监控。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        Zircon作为一个谷歌新开发的微内核,对开发者来说调测机制和调测工具都是全新的,目前Zircon内核支持GDB调试,
    内核程序支持Zxdb调试,程序异常退出支持堆栈打印和符号解析,进程间通信Fidl调测,内核命令行调测,内存调测,
    OOM调测,网络调测,系统日志调测等机制,总体来说,Zircon调测手段较为丰富和成熟。
    下文将对上述调测机制进行介绍。

基础命令

fx scp [$(fx get-device-addr)]:/tmp/filename.ppm /tmp/filename.ppm /* 从fuchisa拷贝到本地 */

GDB调试内核(2022.3 gdb debug不了)

使用qemu启动fuchsia虚拟机,GDB通过网络调试zircon内核镜像文件,对于内核启动流程调试十分便利。

编译

  构建支持GDB调试,使用以下方式编译:

fx set <whatever>
fx build

运行

shell1 $ fx run -- -s -S     (运行fuchisa并暂停等待gdb调试)
shell2 $ gdb out/default/kernel_x64/zircon.elf -x zircon/kernel/scripts/zircon.elf-gdb.py
shell2 (gdb) target extended-remote :1234  (进入gdb命令行后输入该命令)
之后可以使用gdb命令调试zircon内核
(gdb)b lk_main
 (gdb) c

BACKTRACE调测(2022.3可用)

    Fuchsia支持进程异常退出(如非法指针)后打印堆栈,
并可对堆栈进行符号解析,打印函数名,文件名,行号信息,对于进程异常退出后问题定位有很大帮助。

自动回溯

使用symbolize工具可以接收标准输入并对日志中的调用栈进行符号解析,然后在堆栈日志后打印解析符号后的函数调用栈。

运行如下命令等待系统日志和对函数调用栈解析:
shell1 $ fx run -N  (加载fuchisa并支持网络)
shell2 $ fx serve    (启动Zircon服务端)
shell3 $ fx shell <your-cmd>  (运行可能会异常退出的程序)
shell4 $ ./scripts/fx syslog | ./scripts/fx symbolize    (等待Fuchsia syslog日志并将日志作为标准输入给symbolize解析工具,实现日志自动回溯函数调用栈。原理:日志中记录了动态库起始地址,函数偏移等信息)

手动回溯

    在代码的特定位置写入backtrace_request函数(用户态)或thread_print_backtrace函数(内核态),
实现线程特定位置堆栈打印,类似Linux内核的dump_stack()函数。

用户态进程

1 头文件依赖
     #include <lib/backtrace-request/backtrace-request.h>

2 编译依赖
     在修改文件目录BUILD.gn deps项增加路径”$zx/system/ulib/backtrace-request”

3 在希望打印堆栈处增加如下代码:
     void my_function() {
          ...
          backtrace_request();
          ...
     }

解析堆栈

    将带有堆栈的日志拷贝至文件bt-trace.txt,放置于fuchsia目录下,
执行 cat bt-trace.txt | ./scripts/fx symbolize 解析函数符号。

内核态进程

头文件依赖
     #include <kernel/thread.h>

在希望打印堆栈处增加如下代码:
void my_function() {
   thread_print_backtrace(get_current_thread(), __GET_FRAME(0));
}

ZXDB调测(2022.3可用)

     Zxdb是Fuchsia内置一个调试工具,类似于GDB,可以对fuchsia内程序进行
 如断点(break),单步调试(step/next),转储文件调试,进程调试(process),
 汇编(disassemble),打印(print),堆栈(bt)等调试。
参考:https://fuchsia.dev/fuchsia-src/development/debugger/running
以编译workstation为例,core.x64也支持
fx set core.x64  --with //bundles:tools
fx build

调试

shell1 $ fx qemu -N   /* 或者 fx emu -N */(加载fuchisa并支持网络)
shell2 $ fx serve-updates    (启动Zircon服务端)
shell3 $ ffx debug connect   (进入zxdb命令行)
               在zxdb命令行输入:attach 进程名  (等待某个进程启动)
                               attach 进程号   (关联到正在运行进程)
                               break main      (打断点,等待进程运行)
shell4$ fx shell   (进入fuchsia命令行,或者在shell1中运行待调试程序)
                   执行应用程序 如crasher,此时shell3中程序执行到断点main,此后  shell3中可以使用类似GDB的单步调试命令:next,step,print argv[1],continue,quit等
    一些小程序可以直接在zxdb控制台启动,无需attach。
break @main命令中“@main”符号将匹配进程的入口点,这对于Rust来说特别有用。
对于C/C++,它相当于“main”。
break/b lineNum/FuncName:设置一个断点
run/r ProcessName :运行程序
step/s:执行下一行代码
next/n:执行下一个函数
print/p:打印变量值
类似于gdb,zxdb也有一系列进程调试的命令。
attach:附加到进程
process:列出所附加的进程
job:列出附加的工作
thread:列出当前进程中的线程
thread n:切换到线程n
frame:列出当前线程的堆栈帧(需将线程pause)
pause:将线程暂停
continue:将线程恢复运行
bt:显示线程详细调用栈

FIDL调测(2022.3可用)

    /* fidlcat需要--with //bundles:tools选项才能编译 */:
fx set core.x64 --with //bundles:tools --with //examples
fx build
 运行fidlcat,需要在启用网络的情况下启动:
    shell1 $ sudo ip tuntap add dev qemu mode tap user $USER &&  sudo ip link set qemu up
    shell1 $ fx emu --headless -N  // 或者fx qemu -N(/* 若fvm报错,export LANG=C */ /* -N加载fuchisa并支持网络 */)
    shell2 $ fx serve-updates      (启动Zircon服务端)
    shell3 $ fx fidlcat --remote-pid=<pid>
          在shell3中使用fx fidlcat --remote-pid=<pid>关联到正在运行的进程。
如果调试组件未运行,使用fidlcat启动程序:
            fx fidlcat run fuchsia-pkg://fuchsia.com/echo_client_rust#meta/echo_client_rust.cmx
或者使用与构建已知的唯一URL匹配的bash正则表达式指定URL:
            fx fidlcat run "echo_client_cpp_synchronous.*"
            fx fidlcat run echo_client_cpp.cmx
也可以通过名字,关联到一个后续会启动的程序:
            fx fidlcat --remote-name=echo_client

必选项

三个选项--remote-pid, --remote-name和run都可以一起使用。但是,run必须始终是最后一个。
当同时使用--remote-name和run时,仅监视与--remote-name匹配的进程。
示例(echo_server由echo_client启动):
运行并监视echo_client。sh fx fidlcat run echo_client_cpp.cmx
运行并监视echo_client。 sh fx fidlcat --remote-name=echo_client run echo_client_cpp.cmx
运行echo_client并监视echo_server。sh fx fidlcat --remote-name=echo_server run echo_client_cpp.cmx
运行echo_client并监视echo_client和echo_server。 sh fx fidlcat --remote-name=echo run echo_client_cpp.cmx
运行echo_client并监视echo_client和echo_server。 sh fx fidlcat --remote-name=echo_client --remote-name=echo_server run echo_client_cpp.cmx

可选项

   --with-process-info : 在每一行显示名字,进程号,线程号,对于grep有用
    --stack=<value>: 定义需要显示的堆栈帧
                                0  默认值,不显示
                                1  显示1-4帧堆栈
                                2  显示所有堆栈
     如图为显示cowsay程序带--stack参数的fidl流量,黄色部分为详细堆栈。其他使用方法参考:fx fidlcat --help

使用示例

使用fidlcat工具监控ps命令的fidl消息:
shell1 $ fx run -N    (加载fuchisa并支持网络)
shell2 $ fx serve      (启动Zircon服务端)
shell3 $ fx fidlcat --remote-name=ps (fidlcat等待并监控ps命令)
shell4 $ fx shell ps  (新开一个Fuchsia shell,执行ps命令)
             此时shell 3中会打印ps命令所涉及的详细fidl流量。

trace(2022.3可用)

trace Fuchisa启动过程
        shell $ ffx trace record --categories=kernel,kernel:retain --buffer-size=64 --duration=1s --stream
        Trace Complete:
       - trace-2022-03-11T10:38:47.fxt can be viewed using https://ui.perfetto.dev/
       - trace-2022-03-11T10:38:47.json can be viewed using chrome://tracing

syslog

shell1 $ fx qemu -N (加载fuchisa并支持网络)
shell2 $ fx serve-updates   (启动更新serve)
shell3 $ fx log (监听syslog系统日志或其他处理)/* fx klog 查看netsvc提供的内核日志 */
shell4 $ fx shell <cmd> (此时shell3中会打印<cmd>输出的日志)
                       也可以运行fx shell进入zircon命令行后,执行cmd

    如图为使用syslog实时监控系统日志并过滤关键词crasher:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值