aarch64-unknown-fuchsiax86_64-unknown-fuchsia

层级:2

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

目标维护者

请参阅 team 仓库中的 fuchsia.toml 文件以获取当前目标维护者信息。

目录

  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 中有一个针对我们所需 Fuchsia 目标的 Rust 二进制文件。

当前目录结构

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 工具链。最新版本 (14+) 的 clang 应该足以编译 Rust for 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。您可能希望通过在 config.toml 中设置自定义前缀将其安装到其他位置(例如,本地 install 目录):

[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 文件描述了我们包的名称和版本号。每个包都必须包含一个。

如果使用 cargo,则为 pkg/hello_fuchsia.manifest

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

如果使用 rustc,则为 pkg/hello_fuchsia.manifest

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

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

.manifest 文件将用于描述包的内容,方法是将它们安装时的位置与它们在文件系统中的位置相关联。bin/hello_fuchsia= 条目将因 Rust 二进制文件的构建方式而异,因此请相应地选择。

当前目录结构

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

创建 Fuchsia 组件

在 Fuchsia 上,组件需要用 Fuchsia 的标记语言(称为 CML)编写的组件清单。Fuchsia 开发网站包含 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}/ffx package build \
    --api-level $(${SDK_PATH}/tools/${ARCH}/ffx --machine json version | jq .tool_version.api_level) \
    --out pkg/hello_fuchsia_manifest \
    pkg/hello_fuchsia.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}/ffx repository create 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}/ffx repository publish \
    --package pkg/hello_fuchsia_package_manifest \
    pkg/repo

在模拟器上运行 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 \
    --background --repository hello-fuchsia --repo-path pkg-repo

存储库服务器启动并运行后,将其注册到模拟器中运行的目标 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 开发网站上找到。

运行编译器测试套件

本节中的命令假设它们是从您本地的 Rust 源代码检出内部运行的。

cd ${RUST_SRC_PATH}

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

Fuchsia 的测试运行器与 Fuchsia 模拟器交互,位于 src/ci/docker/scripts/fuchsia-test-runner.py。首先,将以下变量添加到您现有的 config-env.sh 中:

# TEST_TOOLCHAIN_TMP_DIR can point anywhere, but it:
#  - must be less than 108 characters, otherwise qemu can't handle the path
#  - must be consistent across calls to this file (don't use `mktemp -d` here)
export TEST_TOOLCHAIN_TMP_DIR="/tmp/rust-tmp"

# Keep existing contents of `config-env.sh` from earlier, including SDK_PATH

然后,我们可以使用该脚本通过以下命令启动我们的测试环境:

( \
    source config-env.sh &&                                                   \
    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}                 \
    --verbose                                                                 \
)

其中 ${RUST_SRC_PATH}/buildconfig.toml 中设置的 build-dir

启动我们的环境后,我们可以像往常一样使用 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

可以使用控制台模式调试器 zxdb 来调试在 Fuchsia 模拟器上运行的组件。我们将演示附加必要的符号路径以调试我们的 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 不要优化或从我们的测试套件二进制文件中剥离调试符号。 我们可以通过将一些新参数传递给 rustc 来通过我们的 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 将附加并加载任何相关的调试符号。