1 # `aarch64-fuchsia` and `x86_64-fuchsia`
5 [Fuchsia] is a modern open source operating system that's simple, secure,
6 updatable, and performant.
12 - Tyler Mandry ([@tmandry](https://github.com/tmandry))
13 - Dan Johnson ([@computerdruid](https://github.com/computerdruid))
14 - David Koloski ([@djkoloski](https://github.com/djkoloski))
15 - Andrew Pollack ([@andrewpollack](https://github.com/andrewpollack))
16 - Joseph Ryan ([@P1n3appl3](https://github.com/P1n3appl3))
18 As the team evolves over time, the specific members listed here may differ from
19 the members reported by the API. The API should be considered to be
20 authoritative if this occurs. Instead of pinging individual members, use
21 `@rustbot ping fuchsia` to contact the team on GitHub.
25 1. [Requirements](#requirements)
26 1. [Walkthrough structure](#walkthrough-structure)
27 1. [Compiling a Rust binary targeting Fuchsia](#compiling-a-rust-binary-targeting-fuchsia)
28 1. [Targeting Fuchsia with rustup and cargo](#targeting-fuchsia-with-rustup-and-cargo)
29 1. [Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)
30 1. [Creating a Fuchsia package](#creating-a-fuchsia-package)
31 1. [Creating a Fuchsia component](#creating-a-fuchsia-component)
32 1. [Building a Fuchsia package](#building-a-fuchsia-package)
33 1. [Publishing a Fuchsia package](#publishing-a-fuchsia-package)
34 1. [Creating a Fuchsia package repository](#creating-a-fuchsia-package-repository)
35 1. [Publishing Fuchsia package to repository](#publishing-fuchsia-package-to-repository)
36 1. [Running a Fuchsia component on an emulator](#running-a-fuchsia-component-on-an-emulator)
37 1. [Starting the Fuchsia emulator](#starting-the-fuchsia-emulator)
38 1. [Watching emulator logs](#watching-emulator-logs)
39 1. [Serving a Fuchsia package](#serving-a-fuchsia-package)
40 1. [Running a Fuchsia component](#running-a-fuchsia-component)
41 1. [`.gitignore` extensions](#gitignore-extensions)
42 1. [Testing](#testing)
43 1. [Running unit tests](#running-unit-tests)
44 1. [Running the compiler test suite](#running-the-compiler-test-suite)
45 1. [Debugging](#debugging)
47 1. [Attaching `zxdb`](#attaching-zxdb)
48 1. [Using `zxdb`](#using-zxdb)
49 1. [Displaying source code in `zxdb`](#displaying-source-code-in-zxdb)
53 This target is cross-compiled from a host environment. You will need a recent
54 copy of the [Fuchsia SDK], which provides the tools, libraries, and binaries
55 required to build and link programs for Fuchsia.
57 Development may also be done from the [source tree].
59 Fuchsia targets support `std` and follow the `sysv64` calling convention on
60 x86_64. Fuchsia binaries use the ELF file format.
62 ## Walkthrough structure
64 This walkthrough will cover:
66 1. Compiling a Rust binary targeting Fuchsia.
67 1. Building a Fuchsia package.
68 1. Publishing and running a Fuchsia package to a Fuchsia emulator.
70 For the purposes of this walkthrough, we will only target `x86_64-fuchsia`.
72 ## Compiling a Rust binary targeting Fuchsia
74 Today, there are two main ways to build a Rust binary targeting Fuchsia
75 using the Fuchsia SDK:
76 1. Allow [rustup] to handle the installation of Fuchsia targets for you.
77 1. Build a toolchain locally that can target Fuchsia.
79 ### Targeting Fuchsia with rustup and cargo
81 The easiest way to build a Rust binary targeting Fuchsia is by allowing [rustup]
82 to handle the installation of Fuchsia targets for you. This can be done by issuing
83 the following commands:
86 rustup target add x86_64-fuchsia
87 rustup target add aarch64-fuchsia
90 After installing our Fuchsia targets, we can now compile a Rust binary that targets
93 To create our Rust project, we can use [`cargo`][cargo] as follows:
95 **From base working directory**
97 cargo new hello_fuchsia
100 The rest of this walkthrough will take place from `hello_fuchsia`, so we can
101 change into that directory now:
107 *Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
108 directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
110 We can edit our `src/main.rs` to include a test as follows:
115 println!("Hello Fuchsia!");
120 assert_eq!(2 + 2, 4);
124 In addition to the standard workspace created, we will want to create a
125 `.cargo/config.toml` file to link necessary libraries
128 **`.cargo/config.toml`**
130 [target.x86_64-fuchsia]
133 "-Lnative=<SDK_PATH>/arch/x64/lib",
134 "-Lnative=<SDK_PATH>/arch/x64/sysroot/lib"
138 *Note: Make sure to fill out `<SDK_PATH>` with the path to the downloaded [Fuchsia SDK].*
140 These options configure the following:
142 * `-Lnative=${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
144 * `-Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
145 libraries from the SDK
147 In total, our new project will look like:
149 **Current directory structure**
159 Finally, we can build our rust binary as:
162 cargo build --target x86_64-fuchsia
165 Now we have a Rust binary at `target/x86_64-fuchsia/debug/hello_fuchsia`,
166 targeting our desired Fuchsia target.
168 **Current directory structure**
182 ### Targeting Fuchsia with a compiler built from source
184 An alternative to the first workflow is to target Fuchsia by using
185 `rustc` built from source.
187 Before building Rust for Fuchsia, you'll need a clang toolchain that supports
188 Fuchsia as well. A recent version (14+) of clang should be sufficient to compile
191 x86-64 and AArch64 Fuchsia targets can be enabled using the following
192 configuration in `config.toml`:
196 target = ["<host_platform>", "aarch64-fuchsia", "x86_64-fuchsia"]
202 download-ci-llvm = false
204 [target.x86_64-fuchsia]
208 [target.aarch64-fuchsia]
213 Though not strictly required, you may also want to use `clang` for your host
217 [target.<host_platform>]
222 By default, the Rust compiler installs itself to `/usr/local` on most UNIX
223 systems. You may want to install it to another location (e.g. a local `install`
224 directory) by setting a custom prefix in `config.toml`:
228 # Make sure to use the absolute path to your install directory
229 prefix = "<RUST_SRC_PATH>/install"
232 Next, the following environment variables must be configured. For example, using
233 a script we name `config-env.sh`:
236 # Configure this environment variable to be the path to the downloaded SDK
237 export SDK_PATH="<SDK path goes here>"
239 export CFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
240 export CXXFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -I${SDK_PATH}/pkg/fdio/include"
241 export LDFLAGS_aarch64_fuchsia="--target=aarch64-fuchsia --sysroot=${SDK_PATH}/arch/arm64/sysroot -L${SDK_PATH}/arch/arm64/lib"
242 export CARGO_TARGET_AARCH64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/arm64/sysroot -Lnative=${SDK_PATH}/arch/arm64/sysroot/lib -Lnative=${SDK_PATH}/arch/arm64/lib"
243 export CFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
244 export CXXFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -I${SDK_PATH}/pkg/fdio/include"
245 export LDFLAGS_x86_64_fuchsia="--target=x86_64-fuchsia --sysroot=${SDK_PATH}/arch/x64/sysroot -L${SDK_PATH}/arch/x64/lib"
246 export CARGO_TARGET_X86_64_FUCHSIA_RUSTFLAGS="-C link-arg=--sysroot=${SDK_PATH}/arch/x64/sysroot -Lnative=${SDK_PATH}/arch/x64/sysroot/lib -Lnative=${SDK_PATH}/arch/x64/lib"
249 Finally, the Rust compiler can be built and installed:
252 (source config-env.sh && ./x.py install)
255 Once `rustc` is installed, we can create a new working directory to work from,
256 `hello_fuchsia` along with `hello_fuchsia/src`:
264 *Note: From this point onwards, all commands will be issued from the `hello_fuchsia/`
265 directory, and all `hello_fuchsia/` prefixes will be removed from references for sake of brevity.*
267 There, we can create a new file named `src/hello_fuchsia.rs`:
269 **`src/hello_fuchsia.rs`**
272 println!("Hello Fuchsia!");
277 assert_eq!(2 + 2, 4);
281 **Current directory structure**
288 Using your freshly installed `rustc`, you can compile a binary for Fuchsia using
289 the following options:
291 * `--target x86_64-fuchsia`/`--target aarch64-fuchsia`: Targets the Fuchsia
292 platform of your choice
293 * `-Lnative ${SDK_PATH}/arch/${ARCH}/lib`: Link against Fuchsia libraries from
295 * `-Lnative ${SDK_PATH}/arch/${ARCH}/sysroot/lib`: Link against Fuchsia sysroot
296 libraries from the SDK
298 Putting it all together:
301 # Configure these for the Fuchsia target of your choice
302 TARGET_ARCH="<x86_64-fuchsia|aarch64-fuchsia>"
306 --target ${TARGET_ARCH} \
307 -Lnative=${SDK_PATH}/arch/${ARCH}/lib \
308 -Lnative=${SDK_PATH}/arch/${ARCH}/sysroot/lib \
309 --out-dir bin src/hello_fuchsia.rs
312 **Current directory structure**
316 ┃ ┗━ hello_fuchsia.rs
321 ## Creating a Fuchsia package
323 Before moving on, double check your directory structure:
325 **Current directory structure**
328 ┣━ src/ (if using rustc)
329 ┃ ┗━ hello_fuchsia.rs ...
331 ┃ ┗━ hello_fuchsia ...
332 ┣━ src/ (if using cargo)
335 ┗━ x86_64-fuchsia/ ...
340 With our Rust binary built, we can move to creating a Fuchsia package.
341 On Fuchsia, a package is the unit of distribution for software. We'll need to
342 create a new package directory where we will place files like our finished
343 binary and any data it may need.
345 To start, make the `pkg`, and `pkg/meta` directories:
352 **Current directory structure**
359 Now, create the following files inside:
361 **`pkg/meta/package`**
364 "name": "hello_fuchsia",
369 The `package` file describes our package's name and version number. Every
370 package must contain one.
372 **`pkg/hello_fuchsia.manifest` if using cargo**
374 bin/hello_fuchsia=target/x86_64-fuchsia/debug/hello_fuchsia
375 lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
376 lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
377 meta/package=pkg/meta/package
378 meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
381 **`pkg/hello_fuchsia.manifest` if using rustc**
383 bin/hello_fuchsia=bin/hello_fuchsia
384 lib/ld.so.1=<SDK_PATH>/arch/x64/sysroot/dist/lib/ld.so.1
385 lib/libfdio.so=<SDK_PATH>/arch/x64/dist/libfdio.so
386 meta/package=pkg/meta/package
387 meta/hello_fuchsia.cm=pkg/meta/hello_fuchsia.cm
390 *Note: Relative manifest paths are resolved starting from the working directory
391 of `pm`. Make sure to fill out `<SDK_PATH>` with the path to the downloaded
394 The `.manifest` file will be used to describe the contents of the package by
395 relating their location when installed to their location on the file system. The
396 `bin/hello_fuchsia=` entry will be different depending on how your Rust binary
397 was built, so choose accordingly.
399 **Current directory structure**
405 ┗━ hello_fuchsia.manifest
408 ### Creating a Fuchsia component
410 On Fuchsia, components require a component manifest written in Fuchsia's markup
411 language called CML. The Fuchsia devsite contains an [overview of CML] and a
412 [reference for the file format]. Here's a basic one that can run our single binary:
414 **`pkg/hello_fuchsia.cml`**
417 include: [ "syslog/client.shard.cml" ],
420 binary: "bin/hello_fuchsia",
425 **Current directory structure**
431 ┣━ hello_fuchsia.manifest
435 Now we can compile that CML into a component manifest:
438 ${SDK_PATH}/tools/${ARCH}/cmc compile \
439 pkg/hello_fuchsia.cml \
440 --includepath ${SDK_PATH}/pkg \
441 -o pkg/meta/hello_fuchsia.cm
444 *Note: `--includepath` tells the compiler where to look for `include`s from our CML.
445 In our case, we're only using `syslog/client.shard.cml`.*
447 **Current directory structure**
453 ┃ ┗━ hello_fuchsia.cm
454 ┣━ hello_fuchsia.manifest
458 ### Building a Fuchsia package
460 Next, we'll build a package manifest as defined by our manifest:
463 ${SDK_PATH}/tools/${ARCH}/pm \
464 -api-level $(${SDK_PATH}/tools/${ARCH}/ffx version -v | grep "api-level" | head -1 | awk -F ' ' '{print $2}') \
465 -o pkg/hello_fuchsia_manifest \
466 -m pkg/hello_fuchsia.manifest \
468 -output-package-manifest pkg/hello_fuchsia_package_manifest
471 This will produce `pkg/hello_fuchsia_manifest/` which is a package manifest we can
472 publish directly to a repository.
474 **Current directory structure**
480 ┃ ┗━ hello_fuchsia.cm
481 ┣━ hello_fuchsia_manifest/
483 ┣━ hello_fuchsia.manifest
485 ┗━ hello_fuchsia_package_manifest
488 We are now ready to publish the package.
490 ## Publishing a Fuchsia package
492 With our package and component manifests setup,
493 we can now publish our package. The first step will
494 be to create a Fuchsia package repository to publish
497 ### Creating a Fuchsia package repository
499 We can set up our repository with:
502 ${SDK_PATH}/tools/${ARCH}/pm newrepo \
506 **Current directory structure**
512 ┃ ┗━ hello_fuchsia.cm
513 ┣━ hello_fuchsia_manifest/
517 ┣━ hello_fuchsia.manifest
519 ┗━ hello_fuchsia_package_manifest
522 ## Publishing Fuchsia package to repository
524 We can publish our new package to that repository with:
527 ${SDK_PATH}/tools/${ARCH}/pm publish \
529 -lp -f <(echo "pkg/hello_fuchsia_package_manifest")
532 Then we can add the repository to `ffx`'s package server as `hello-fuchsia` using:
535 ${SDK_PATH}/tools/${ARCH}/ffx repository add-from-pm \
540 ## Running a Fuchsia component on an emulator
542 At this point, we are ready to run our Fuchsia
543 component. For reference, our final directory
544 structure will look like:
546 **Final directory structure**
549 ┣━ src/ (if using rustc)
550 ┃ ┗━ hello_fuchsia.rs ...
552 ┃ ┗━ hello_fuchsia ...
553 ┣━ src/ (if using cargo)
556 ┃ ┗━ x86_64-fuchsia/ ...
558 ┃ ┗━ hello_fuchsia ...
562 ┃ ┗━ hello_fuchsia.cm
563 ┣━ hello_fuchsia_manifest/
567 ┣━ hello_fuchsia.manifest
569 ┗━ hello_fuchsia_package_manifest
572 ### Starting the Fuchsia emulator
574 Start a Fuchsia emulator in a new terminal using:
577 ${SDK_PATH}/tools/${ARCH}/ffx product-bundle get workstation_eng.qemu-${ARCH}
578 ${SDK_PATH}/tools/${ARCH}/ffx emu start workstation_eng.qemu-${ARCH} --headless
581 ### Watching emulator logs
583 Once the emulator is running, open a separate terminal to watch the emulator logs:
585 **In separate terminal**
587 ${SDK_PATH}/tools/${ARCH}/ffx log \
591 ### Serving a Fuchsia package
593 Now, start a package repository server to serve our
594 package to the emulator:
597 ${SDK_PATH}/tools/${ARCH}/ffx repository server start
600 Once the repository server is up and running, register it with the target Fuchsia system running in the emulator:
603 ${SDK_PATH}/tools/${ARCH}/ffx target repository register \
604 --repository hello-fuchsia
607 ### Running a Fuchsia component
609 Finally, run the component:
612 ${SDK_PATH}/tools/${ARCH}/ffx component run \
613 /core/ffx-laboratory:hello_fuchsia \
614 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
617 On reruns of the component, the `--recreate` argument may also need to be
621 ${SDK_PATH}/tools/${ARCH}/ffx component run \
623 /core/ffx-laboratory:hello_fuchsia \
624 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
627 ## `.gitignore` extensions
629 Optionally, we can create/extend our `.gitignore` file to ignore files and
630 directories that are not helpful to track:
634 pkg/meta/hello_fuchsia.cm
635 pkg/hello_fuchsia_manifest
636 pkg/hello_fuchsia_package_manifest
641 ### Running unit tests
643 Tests can be run in the same way as a regular binary.
645 * If using `cargo`, you can simply pass `test --no-run`
646 to the `cargo` invocation and then repackage and rerun the Fuchsia package. From our previous example,
647 this would look like `cargo test --target x86_64-fuchsia --no-run`, and moving the executable
648 binary path found from the line `Executable unittests src/main.rs (target/x86_64-fuchsia/debug/deps/hello_fuchsia-<HASH>)`
649 into `pkg/hello_fuchsia.manifest`.
651 * If using the compiled `rustc`, you can simply pass `--test`
652 to the `rustc` invocation and then repackage and rerun the Fuchsia package.
654 The test harness will run the applicable unit tests.
656 Often when testing, you may want to pass additional command line arguments to
657 your binary. Additional arguments can be set in the component manifest:
659 **`pkg/hello_fuchsia.cml`**
662 include: [ "syslog/client.shard.cml" ],
665 binary: "bin/hello_fuchsia",
671 This will pass the argument `it_works` to the binary, filtering the tests to
672 only those tests that match the pattern. There are many more configuration
673 options available in CML including environment variables. More documentation is
674 available on the [Fuchsia devsite].
676 ### Running the compiler test suite
678 The commands in this section assume that they are being run from inside your
679 local Rust source checkout:
685 To run the Rust test suite on an emulated Fuchsia device, you must install the
686 Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)"
687 for the steps to build locally.
689 You'll also need to download a copy of the Fuchsia SDK. The current minimum
690 supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1).
692 Fuchsia's test runner interacts with the Fuchsia emulator and is located at
693 `src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our
694 test environment with:
697 src/ci/docker/scripts/fuchsia-test-runner.py start
698 --rust ${RUST_SRC_PATH}/install
700 --target-arch {x64,arm64}
703 Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
704 `${SDK_PATH}` is the path to the downloaded and unzipped SDK.
706 Once our environment is started, we can run our tests using `x.py` as usual. The
707 test runner script will run the compiled tests on an emulated Fuchsia device. To
708 run the full `src/test/ui` test suite:
712 source config-env.sh && \
714 --config config.toml \
717 --target x86_64-fuchsia \
718 --run=always --jobs 1 \
719 --test-args --target-rustcflags \
721 --test-args --target-rustcflags \
722 --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
723 --test-args --target-rustcflags \
725 --test-args --target-rustcflags \
726 --test-args ${SDK_PATH}/arch/{x64|arm64}/lib \
727 --test-args --target-rustcflags \
728 --test-args -Cpanic=abort \
729 --test-args --target-rustcflags \
730 --test-args -Zpanic_abort_tests \
731 --test-args --remote-test-client \
732 --test-args src/ci/docker/scripts/fuchsia-test-runner.py \
736 *Note: The test suite cannot be run in parallel at the moment, so `x.py`
737 must be run with `--jobs 1` to ensure only one test runs at a time.*
739 When finished, the test runner can be used to stop the test environment:
742 src/ci/docker/scripts/fuchsia-test-runner.py stop
749 Debugging components running on a Fuchsia emulator can be done using the
750 console-mode debugger: [zxdb]. We will demonstrate attaching necessary symbol
751 paths to debug our `hello-fuchsia` component.
755 In a separate terminal, issue the following command from our `hello_fuchsia`
756 directory to launch `zxdb`:
758 **In separate terminal**
760 ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
761 --symbol-path target/x86_64-fuchsia/debug
764 * `--symbol-path` gets required symbol paths, which are
765 necessary for stepping through your program.
767 The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can
768 display Rust and/or Fuchsia source code in your debugging session.
772 Once launched, you will be presented with the window:
775 Connecting (use "disconnect" to cancel)...
776 Connected successfully.
777 👉 To get started, try "status" or "help".
781 To attach to our program, we can run:
784 [zxdb] attach hello_fuchsia
789 Waiting for process matching "hello_fuchsia".
790 Type "filter" to see the current filters.
793 Next, we can create a breakpoint at main using "b main":
801 Created Breakpoint 1 @ main
804 Finally, we can re-run the "hello_fuchsia" component from our original
808 ${SDK_PATH}/tools/${ARCH}/ffx component run \
810 fuchsia-pkg://hello-fuchsia/hello_fuchsia_manifest#meta/hello_fuchsia.cm
813 Once our component is running, our `zxdb` window will stop execution
814 in our main as desired:
818 Breakpoint 1 now matching 1 addrs for main
819 🛑 on bp 1 hello_fuchsia::main() • main.rs:2
821 ▶ 2 println!("Hello Fuchsia!");
827 `zxdb` has similar commands to other debuggers like [gdb].
828 To list the available commands, run "help" in the
829 `zxdb` window or visit [the zxdb documentation].
839 Type "help <command>" for command-specific help.
841 Other help topics (see "help <topic>")
845 ### Displaying source code in `zxdb`
847 By default, the debugger will not be able to display
848 source code while debugging. For our user code, we displayed
849 source code by pointing our debugger to our debug binary via
850 the `--symbol-path` arg. To display library source code in
851 the debugger, you must provide paths to the source using
852 `--build-dir`. For example, to display the Rust and Fuchsia
856 ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
857 --symbol-path target/x86_64-fuchsia/debug \
858 --build-dir ${RUST_SRC_PATH}/rust \
859 --build-dir ${FUCHSIA_SRC_PATH}/fuchsia/out/default
862 * `--build-dir` links against source code paths, which
863 are not strictly necessary for debugging, but is a nice-to-have
864 for displaying source code in `zxdb`.
866 Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
869 [Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
870 [Fuchsia]: https://fuchsia.dev/
871 [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
872 [rustup]: https://rustup.rs/
873 [cargo]: ../../cargo/index.html
874 [Fuchsia SDK]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core
875 [overview of CML]: https://fuchsia.dev/fuchsia-src/concepts/components/v2/component_manifests
876 [reference for the file format]: https://fuchsia.dev/reference/cml
877 [Fuchsia devsite]: https://fuchsia.dev/reference/cml
878 [not currently supported]: https://fxbug.dev/105393
879 [zxdb]: https://fuchsia.dev/fuchsia-src/development/debugger
880 [gdb]: https://www.sourceware.org/gdb/
881 [the zxdb documentation]: https://fuchsia.dev/fuchsia-src/development/debugger
882 [fdio]: https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/lib/fdio/