aarch64-unknown-fuchsiax86_64-unknown-fuchsia

层级:2

Fuchsia 是一个现代的开源操作系统,它简单、安全、可更新且性能出色。

目标维护者

The Fuchsia team

随着团队的不断发展,这里列出的具体成员可能与 API 报告的成员不同。如果发生这种情况,API 应被视为权威。不要 ping 某个成员,而是使用 @rustbot ping fuchsia 在 GitHub 上联系团队。

目录

  1. 要求
  2. 演练结构
  3. 编译针对 Fuchsia 的 Rust 二进制文件
    1. 使用 rustup 和 cargo 针对 Fuchsia
    2. 使用从源代码构建的编译器针对 Fuchsia
  4. 创建 Fuchsia 包
    1. 创建 Fuchsia 组件
    2. 构建 Fuchsia 包
  5. 发布 Fuchsia 包
    1. 创建 Fuchsia 包仓库
    2. 将 Fuchsia 包发布到仓库
  6. 在模拟器上运行 Fuchsia 组件
    1. 启动 Fuchsia 模拟器
    2. 查看模拟器日志
    3. 提供 Fuchsia 包
    4. 运行 Fuchsia 组件
  7. .gitignore 扩展
  8. 测试
    1. 运行单元测试
    2. 运行编译器测试套件
  9. 调试
    1. zxdb
    2. 附加 zxdb
    3. 使用 zxdb
    4. zxdb 中显示源代码

要求

此目标是从主机环境交叉编译的。您需要一个最新的 Fuchsia SDK 副本,它提供了构建和链接 Fuchsia 程序所需的工具、库和二进制文件。

也可以从 源代码树 进行开发。

Fuchsia 目标支持 std 并在 x86_64 上遵循 sysv64 调用约定。Fuchsia 二进制文件使用 ELF 文件格式。

演练结构

本演练将涵盖

  1. 编译针对 Fuchsia 的 Rust 二进制文件。
  2. 构建 Fuchsia 包。
  3. 将 Fuchsia 包发布并运行到 Fuchsia 模拟器。

在本演练中,我们将只针对 x86_64-unknown-fuchsia

编译针对 Fuchsia 的 Rust 二进制文件

目前,使用 Fuchsia SDK 构建针对 Fuchsia 的 Rust 二进制文件主要有两种方法

  1. 允许 rustup 为您处理 Fuchsia 目标的安装。
  2. 在本地构建一个可以针对 Fuchsia 的工具链。

使用 rustup 和 cargo 针对 Fuchsia

构建针对 Fuchsia 的 Rust 二进制文件最简单的方法是允许 rustup 为您处理 Fuchsia 目标的安装。这可以通过发出以下命令来完成

rustup target add x86_64-unknown-fuchsia
rustup target add aarch64-unknown-fuchsia

安装 Fuchsia 目标后,我们现在可以编译一个针对 Fuchsia 的 Rust 二进制文件。

要创建我们的 Rust 项目,我们可以使用 cargo,如下所示

从基本工作目录

cargo new hello_fuchsia

本演练的其余部分将在 hello_fuchsia 中进行,因此我们现在可以更改到该目录

cd hello_fuchsia

注意:从现在开始,所有命令都将在 hello_fuchsia/ 目录中发出,并且为了简洁起见,所有 hello_fuchsia/ 前缀都将从引用中删除。

我们可以编辑我们的 src/main.rs 以包含一个测试,如下所示

src/main.rs

fn main() {
    println!("Hello Fuchsia!");
}

#[test]
fn it_works() {
    assert_eq!(2 + 2, 4);
}

除了创建的标准工作区之外,我们还需要创建一个 .cargo/config.toml 文件,以便在编译期间链接必要的库

.cargo/config.toml

[target.x86_64-unknown-fuchsia]

rustflags = [
    "-Lnative=<SDK_PATH>/arch/x64/lib",
    "-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
]

注意:确保用下载的 Fuchsia SDK 的路径填充 <SDK_PATH>

这些选项配置以下内容

  • -Lnative=${SDK_PATH}/arch/${ARCH}/lib:链接 SDK 中的 Fuchsia 库
  • -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib:链接 SDK 中的 Fuchsia sysroot 库

总的来说,我们的新项目将如下所示

当前目录结构

hello_fuchsia/
┣━ src/
┃  ┗━ main.rs
┣━ Cargo.toml
┗━ .cargo/
   ┗━ config.toml

最后,我们可以构建我们的 rust 二进制文件,如下所示

cargo build --target x86_64-unknown-fuchsia

现在我们在 target/x86_64-unknown-fuchsia/debug/hello_fuchsia 中有一个 Rust 二进制文件,它针对我们想要的 Fuchsia 目标。

当前目录结构

hello_fuchsia/
┣━ src/
┃  ┗━ main.rs
┣━ target/
┃  ┗━ x86_64-unknown-fuchsia/
┃     ┗━ debug/
┃        ┗━ hello_fuchsia
┣━ Cargo.toml
┗━ .cargo/
   ┗━ config.toml

使用从源代码构建的编译器针对 Fuchsia

第一种工作流程的另一种方法是使用从源代码构建的 rustc 来针对 Fuchsia。

在为 Fuchsia 构建 Rust 之前,您需要一个支持 Fuchsia 的 clang 工具链。最新的 clang 版本(14+)应该足以编译 Rust 以用于 Fuchsia。

可以使用 config.toml 中的以下配置启用 x86-64 和 AArch64 Fuchsia 目标

[build]
target = ["<host_platform>", "aarch64-unknown-fuchsia", "x86_64-unknown-fuchsia"]

[rust]
lld = true

[llvm]
download-ci-llvm = false

[target.x86_64-unknown-fuchsia]
cc = "clang"
cxx = "clang++"

[target.aarch64-unknown-fuchsia]
cc = "clang"
cxx = "clang++"

虽然不是严格要求,但您可能还想将 clang 用于您的主机目标

[target.<host_platform>]
cc = "clang"
cxx = "clang++"

默认情况下,Rust 编译器会将自身安装到大多数 UNIX 系统上的 /usr/local。您可能希望将其安装到另一个位置(例如,本地 install 目录),方法是在 config.toml 中设置自定义前缀

[install]
# Make sure to use the absolute path to your install directory
prefix = "<RUST_SRC_PATH>/install"

接下来,必须配置以下环境变量。例如,使用我们命名的脚本 config-env.sh

# Configure this environment variable to be the path to the downloaded SDK
export SDK_PATH="<SDK path goes here>"

export CFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
export CXXFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
export LDFLAGS_aarch64_unknown_fuchsia="--target=aarch64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib"
export CARGO_TARGET_AARCH64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib"
export CFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
export CXXFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
export LDFLAGS_x86_64_unknown_fuchsia="--target=x86_64-unknown-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib"
export CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib"

最后,可以构建和安装 Rust 编译器

(source config-env.sh && ./x.py install)

安装 rustc 后,我们可以创建一个新的工作目录来工作,hello_fuchsia 以及 hello_fuchsia/src

mkdir hello_fuchsia
cd hello_fuchsia
mkdir src

注意:从现在开始,所有命令都将在 hello_fuchsia/ 目录中发出,并且为了简洁起见,所有 hello_fuchsia/ 前缀都将从引用中删除。

在那里,我们可以创建一个名为 src/hello_fuchsia.rs 的新文件

src/hello_fuchsia.rs

fn main() {
    println!("Hello Fuchsia!");
}

#[test]
fn it_works() {
    assert_eq!(2 + 2, 4);
}

当前目录结构

hello_fuchsia/
┗━ src/
    ┗━ hello_fuchsia.rs

使用您新安装的 rustc,您可以使用以下选项编译针对 Fuchsia 的二进制文件

  • --target x86_64-unknown-fuchsia/--target aarch64-unknown-fuchsia:针对您选择的 Fuchsia 平台
  • -Lnative ${SDK_PATH}/arch/${ARCH}/lib:链接 SDK 中的 Fuchsia 库
  • -Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib:链接 SDK 中的 Fuchsia sysroot 库

将所有内容整合在一起

# Configure these for the Fuchsia target of your choice
TARGET_ARCH="<x86_64-unknown-fuchsia|aarch64-unknown-fuchsia>"
ARCH="<x64|aarch64>"

rustc \
    --target ${TARGET_ARCH} \
    -Lnative=${SDK_PATH}/arch/${ARCH}/lib \
    -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib \
    --out-dir bin src/hello_fuchsia.rs

当前目录结构

hello_fuchsia/
┣━ src/
┃   ┗━ hello_fuchsia.rs
┗━ bin/
   ┗━ hello_fuchsia

创建 Fuchsia 包

在继续之前,请仔细检查您的目录结构

当前目录结构

hello_fuchsia/
┣━ src/                         (if using rustc)
┃   ┗━ hello_fuchsia.rs         ...
┣━ bin/                         ...
┃  ┗━ hello_fuchsia             ...
┣━ src/                         (if using cargo)
┃  ┗━ main.rs                   ...
┗━ target/                      ...
   ┗━ x86_64-unknown-fuchsia/   ...
      ┗━ debug/                 ...
         ┗━ hello_fuchsia       ...

构建好 Rust 二进制文件后,我们可以开始创建 Fuchsia 包。在 Fuchsia 上,包是软件的发布单位。我们需要创建一个新的包目录,并将完成的二进制文件以及它可能需要的任何数据放在其中。

首先,创建 pkgpkg/meta 目录

mkdir pkg
mkdir pkg/meta

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┗━ meta/

现在,在其中创建以下文件

pkg/meta/package

{
  "name": "hello_fuchsia",
  "version": "0"
}

package 文件描述了我们包的名称和版本号。每个包都必须包含一个。

pkg/hello_fuchsia.manifest(如果使用 cargo)

bin/hello_fuchsia=target/x86_64-unknown-fuchsia/debug/hello_fuchsia
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
meta/package=pkg/meta/package
meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm

pkg/hello_fuchsia.manifest(如果使用 rustc)

bin/hello_fuchsia=bin/hello_fuchsia
lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
meta/package=pkg/meta/package
meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm

注意:相对清单路径是从 pm 的工作目录开始解析的。确保用下载的 SDK 的路径填充 <SDK_PATH>

.manifest 文件用于描述包的内容,通过关联安装时它们的位置和它们在文件系统中的位置。bin/hello_fuchsia= 条目将根据 Rust 二进制文件的构建方式而有所不同,因此请根据情况选择。

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┣━ meta/
   ┃  ┗━ package
   ┗━ hello_fuchsia.manifest

创建 Fuchsia 组件

在 Fuchsia 上,组件需要一个用 Fuchsia 标记语言 CML 编写的组件清单。Fuchsia devsite 包含一个 CML 概述 和一个 文件格式参考。以下是一个可以运行我们单个二进制文件的简单示例

pkg/hello_fuchsia.cml

{
    include: [ "syslog/client.shard.cml" ],
    program: {
        runner: "elf",
        binary: "bin/hello_fuchsia",
    },
}

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┣━ meta/
   ┃  ┗━ package
   ┣━ hello_fuchsia.manifest
   ┗━ hello_fuchsia.cml

现在我们可以将该 CML 编译成一个组件清单

${SDK_PATH}/tools/${ARCH}/cmc compile \
    pkg/hello_fuchsia.cml \
    --includepath ${SDK_PATH}/pkg \
    -o pkg/meta/hello_fuchsia.cm

注意:--includepath 告诉编译器在哪里查找来自我们 CML 的 include。在我们的例子中,我们只使用 syslog/client.shard.cml

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┣━ meta/
   ┃  ┣━ package
   ┃  ┗━ hello_fuchsia.cm
   ┣━ hello_fuchsia.manifest
   ┗━ hello_fuchsia.cml

构建 Fuchsia 包

接下来,我们将根据我们的清单构建一个包清单

${SDK_PATH}/tools/${ARCH}/pm \
    -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 |  awk -F ' ' '{print $2}') \
    -o pkg/hello_fuchsia_manifest \
    -m pkg/hello_fuchsia.manifest \
    build \
    -output-package-manifest pkg/hello_fuchsia_package_manifest

这将生成 pkg/hello_fuchsia_manifest/,这是一个我们可以直接发布到存储库的包清单。

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┣━ meta/
   ┃  ┣━ package
   ┃  ┗━ hello_fuchsia.cm
   ┣━ hello_fuchsia_manifest/
   ┃  ┗━ ...
   ┣━ hello_fuchsia.manifest
   ┣━ hello_fuchsia.cml
   ┗━ hello_fuchsia_package_manifest

现在我们准备发布包了。

发布 Fuchsia 包

在我们的包和组件清单设置好之后,我们现在可以发布我们的包了。第一步是创建一个 Fuchsia 包存储库来发布。

创建 Fuchsia 包仓库

我们可以使用以下命令设置我们的存储库

${SDK_PATH}/tools/${ARCH}/pm newrepo \
    -repo pkg/repo

当前目录结构

hello_fuchsia/
┗━ pkg/
   ┣━ meta/
   ┃  ┣━ package
   ┃  ┗━ hello_fuchsia.cm
   ┣━ hello_fuchsia_manifest/
   ┃  ┗━ ...
   ┣━ repo/
   ┃  ┗━ ...
   ┣━ hello_fuchsia.manifest
   ┣━ hello_fuchsia.cml
   ┗━ hello_fuchsia_package_manifest

将 Fuchsia 包发布到仓库

我们可以使用以下命令将我们的新包发布到该存储库

${SDK_PATH}/tools/${ARCH}/pm publish \
    -repo pkg/repo \
    -lp -f <(echo "pkg/hello_fuchsia_package_manifest")

然后,我们可以使用以下命令将存储库添加到 ffx 的包服务器中,作为 hello-fuchsia

${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
    pkg/repo \
    -r hello-fuchsia

在模拟器上运行 Fuchsia 组件

此时,我们已经准备好运行我们的 Fuchsia 组件了。作为参考,我们的最终目录结构将如下所示

最终目录结构

hello_fuchsia/
┣━ src/                         (if using rustc)
┃   ┗━ hello_fuchsia.rs         ...
┣━ bin/                         ...
┃  ┗━ hello_fuchsia             ...
┣━ src/                         (if using cargo)
┃  ┗━ main.rs                   ...
┣━ target/                      ...
┃  ┗━ x86_64-unknown-fuchsia/   ...
┃     ┗━ debug/                 ...
┃        ┗━ hello_fuchsia       ...
┗━ pkg/
   ┣━ meta/
   ┃  ┣━ package
   ┃  ┗━ hello_fuchsia.cm
   ┣━ hello_fuchsia_manifest/
   ┃  ┗━ ...
   ┣━ repo/
   ┃  ┗━ ...
   ┣━ hello_fuchsia.manifest
   ┣━ hello_fuchsia.cml
   ┗━ hello_fuchsia_package_manifest

启动 Fuchsia 模拟器

在新的终端中使用以下命令启动 Fuchsia 模拟器

${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless

查看模拟器日志

模拟器运行后,打开一个单独的终端来查看模拟器日志

在单独的终端中

${SDK_PATH}/tools/${ARCH}/ffx log \
    --since now

提供 Fuchsia 包

现在,启动一个包存储库服务器,将我们的包提供给模拟器

${SDK_PATH}/tools/${ARCH}/ffx repository server start

存储库服务器启动并运行后,将其注册到模拟器中运行的目标 Fuchsia 系统

${SDK_PATH}/tools/${ARCH}/ffx target repository register \
    --repository hello-fuchsia

运行 Fuchsia 组件

最后,运行组件

${SDK_PATH}/tools/${ARCH}/ffx component run \
    /core/ffx-laboratory:hello_fuchsia \
    fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm

在重新运行组件时,可能还需要传递 --recreate 参数。

${SDK_PATH}/tools/${ARCH}/ffx component run \
    --recreate \
    /core/ffx-laboratory:hello_fuchsia \
    fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm

.gitignore 扩展

可选地,我们可以创建/扩展我们的 .gitignore 文件,以忽略不方便跟踪的文件和目录

pkg/repo
pkg/meta/hello_fuchsia.cm
pkg/hello_fuchsia_manifest
pkg/hello_fuchsia_package_manifest

测试

运行单元测试

测试可以像普通二进制文件一样运行。

  • 如果使用 cargo,你可以简单地将 test --no-run 传递给 cargo 调用,然后重新打包并重新运行 Fuchsia 包。从我们之前的示例来看,这将类似于 cargo test --target x86_64-unknown-fuchsia --no-run,并将从 Executable unittests src/main.rs (target/x86_64-unknown-fuchsia/debug/deps/hello_fuchsia-<HASH>) 行中找到的可执行二进制文件路径移动到 pkg/hello_fuchsia.manifest 中。

  • 如果使用编译后的 rustc,你可以简单地将 --test 传递给 rustc 调用,然后重新打包并重新运行 Fuchsia 包。

测试工具将运行适用的单元测试。

在测试时,你可能希望将额外的命令行参数传递给你的二进制文件。可以在组件清单中设置额外的参数

pkg/hello_fuchsia.cml

{
    include: [ "syslog/client.shard.cml" ],
    program: {
        runner: "elf",
        binary: "bin/hello_fuchsia",
        args: ["it_works"],
    },
}

这将把参数 it_works 传递给二进制文件,将测试过滤到仅匹配该模式的测试。CML 中还有许多其他配置选项,包括环境变量。有关更多文档,请访问 Fuchsia devsite

运行编译器测试套件

本节中的命令假设它们是在本地 Rust 源代码检出目录中运行的

cd ${RUST_SRC_PATH}

要在模拟的 Fuchsia 设备上运行 Rust 测试套件,你还需要下载 Fuchsia SDK 的副本。当前支持的最低 SDK 版本是 10.20221207.2.89

Fuchsia 的测试运行器与 Fuchsia 模拟器交互,位于 src/ci/docker/scripts/fuchsia-test-runner.py。我们可以使用它来启动我们的测试环境

( \
    src/ci/docker/scripts/fuchsia-test-runner.py start                        \
    --rust-build ${RUST_SRC_PATH}/build                                       \
    --sdk ${SDK_PATH}                                                         \
    --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}                 \
)

其中 ${RUST_SRC_PATH}/build 是在 config.toml 中设置的 build-dir${SDK_PATH} 是下载并解压缩的 SDK 的路径。

环境启动后,我们可以像往常一样使用 x.py 运行测试。测试运行器脚本将在模拟的 Fuchsia 设备上运行编译后的测试。要运行完整的 tests/ui 测试套件

( \
    source config-env.sh &&                                                   \
    ./x.py                                                                    \
    --config config.toml                                                      \
    --stage=2                                                                 \
    test tests/ui                                                             \
    --target x86_64-unknown-fuchsia                                           \
    --run=always                                                              \
    --test-args --target-rustcflags                                           \
    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
    --test-args --target-rustcflags                                           \
    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
    --test-args --target-rustcflags                                           \
    --test-args -Clink-arg=--undefined-version                                \
    --test-args --remote-test-client                                          \
    --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
)

默认情况下,x.py 使用 panic=unwind 编译测试二进制文件。如果你使用 -Cpanic=abort 构建了 Rust 工具链,你需要告诉 x.py 也使用 panic=abort 编译测试二进制文件

    --test-args --target-rustcflags                                           \
    --test-args -Cpanic=abort                                                 \
    --test-args --target-rustcflags                                           \
    --test-args -Zpanic_abort_tests                                           \

测试完成后,可以使用测试运行器停止测试环境

src/ci/docker/scripts/fuchsia-test-runner.py stop

调试

zxdb

可以使用控制台模式调试器调试在 Fuchsia 模拟器上运行的组件:zxdb。我们将演示如何附加必要的符号路径来调试我们的 hello-fuchsia 组件。

附加 zxdb

在单独的终端中,从我们的 hello_fuchsia 目录中发出以下命令来启动 zxdb

在单独的终端中

${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
    --symbol-path target/x86_64-unknown-fuchsia/debug
  • --symbol-path 获取所需的符号路径,这些路径对于逐步执行程序是必要的。

"zxdb 中显示源代码" 部分描述了如何在调试会话中显示 Rust 和/或 Fuchsia 源代码。

使用 zxdb

启动后,你将看到以下窗口

Connecting (use "disconnect" to cancel)...
Connected successfully.
👉 To get started, try "status" or "help".
[zxdb]

要附加到我们的程序,我们可以运行

[zxdb] attach hello_fuchsia

预期输出

Waiting for process matching "hello_fuchsia".
Type "filter" to see the current filters.

接下来,我们可以使用 "b main" 在 main 中创建一个断点

[zxdb] b main

预期输出

Created Breakpoint 1 @ main

最后,我们可以从原始终端重新运行 "hello_fuchsia" 组件

${SDK_PATH}/tools/${ARCH}/ffx component run \
    --recreate \
    fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm

组件运行后,我们的 zxdb 窗口将按预期在 main 中停止执行

预期输出

Breakpoint 1 now matching 1 addrs for main
🛑 on bp 1 hello_fuchsia::main() • main.rs:2
   1 fn main() {
 ▶ 2     println!("Hello Fuchsia!");
   3 }
   4
[zxdb]

zxdb 具有与其他调试器(如 gdb)类似的命令。要列出可用的命令,请在 zxdb 窗口中运行 "help",或访问 zxdb 文档

[zxdb] help

预期输出

Help!

  Type "help <command>" for command-specific help.

Other help topics (see "help <topic>")
...

zxdb 中显示源代码

默认情况下,调试器在调试时将无法显示源代码。对于我们的用户代码,我们通过将调试器指向我们的调试二进制文件(通过 --symbol-path 参数)来显示源代码。要在调试器中显示库源代码,必须使用 --build-dir 提供源代码路径。例如,要显示 Rust 和 Fuchsia 源代码

${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
    --symbol-path target/x86_64-unknown-fuchsia/debug \
    --build-dir ${RUST_SRC_PATH}/rust \
    --build-dir ${FUCHSIA_SRC_PATH}/fuchsia/out/default
  • --build-dir 与源代码路径链接,这些路径对于调试来说不是严格必要的,但对于在 zxdb 中显示源代码来说是一个不错的选择。

链接到 Fuchsia 检出可以帮助调试 Fuchsia 库,例如 fdio

调试编译器测试套件

调试编译器测试套件需要一些特殊的配置

首先,我们必须正确配置 zxdb,以便它能够找到测试的调试符号和源信息。测试运行器可以为我们做到这一点

src/ci/docker/scripts/fuchsia-test-runner.py debug                            \
    --rust-src ${RUST_SRC_PATH}                                               \
    --fuchsia-src ${FUCHSIA_SRC_PATH}                                         \
    --test ${TEST}

其中 ${TEST} 相对于 Rust 的 tests 目录(例如 ui/abi/...)。

这将启动一个为正在运行的特定测试正确配置的 zxdb 会话。所有三个参数都是可选的,因此如果你没有下载 Fuchsia 源代码,可以省略 --fuchsia-src。现在是设置任何所需断点的好时机,例如 b main

接下来,我们必须告诉 x.py 不要优化或从我们的测试套件二进制文件中剥离调试符号。我们可以通过通过 x.py 调用传递一些新的参数来做到这一点。完整的调用是

( \
    source config-env.sh &&                                                   \
    ./x.py                                                                    \
    --config config.toml                                                      \
    --stage=2                                                                 \
    test tests/${TEST}                                                        \
    --target x86_64-unknown-fuchsia                                           \
    --run=always                                                              \
    --test-args --target-rustcflags                                           \
    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib             \
    --test-args --target-rustcflags                                           \
    --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib                     \
    --test-args --target-rustcflags                                           \
    --test-args -Clink-arg=--undefined-version                                \
    --test-args --target-rustcflags                                           \
    --test-args -Cdebuginfo=2                                                 \
    --test-args --target-rustcflags                                           \
    --test-args -Copt-level=0                                                 \
    --test-args --target-rustcflags                                           \
    --test-args -Cstrip=none                                                  \
    --test-args --remote-test-client                                          \
    --test-args src/ci/docker/scripts/fuchsia-test-runner.py                  \
)

如果你使用 panic=abort 构建了 Rust 工具链,请确保包含前面的标志,以便你的测试二进制文件也使用 panic=abort 编译。

运行此命令后,测试套件二进制文件将运行,zxdb 将附加并加载任何相关的调试符号。