Skip to content

Commit

Permalink
Update fuchsia-test-runner.py and docs
Browse files Browse the repository at this point in the history
This updates the test runner to the latest version of the SDK and fixes
debugging support for Rust source code.
  • Loading branch information
David Koloski committed Feb 24, 2023
1 parent f4f5fc3 commit 6e7902b
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 27 deletions.
82 changes: 69 additions & 13 deletions src/ci/docker/scripts/fuchsia-test-runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,9 +507,8 @@ def start(self):
bin/{exe_name}={bin_path}
lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so
lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so
lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so
lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
"""

TEST_ENV_VARS: ClassVar[List[str]] = [
Expand Down Expand Up @@ -844,23 +843,34 @@ def debug(self, args):
"--",
"--build-id-dir",
os.path.join(self.sdk_dir, ".build-id"),
"--build-id-dir",
os.path.join(self.libs_dir(), ".build-id"),
]

# Add rust source if it's available
if args.rust_src is not None:
libs_build_id_path = os.path.join(self.libs_dir(), ".build-id")
if os.path.exists(libs_build_id_path):
# Add .build-id symbols if installed libs have been stripped into a
# .build-id directory
command += [
"--build-dir",
args.rust_src,
"--build-id-dir",
libs_build_id_path,
]
else:
# If no .build-id directory is detected, then assume that the shared
# libs contain their debug symbols
command += [
f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib",
]

# Add rust source if it's available
rust_src_map = None
if args.rust_src is not None:
# This matches the remapped prefix used by compiletest. There's no
# clear way that we can determine this, so it's hard coded.
rust_src_map = f"/rustc/FAKE_PREFIX={args.rust_src}"

# Add fuchsia source if it's available
fuchsia_src_map = None
if args.fuchsia_src is not None:
command += [
"--build-dir",
os.path.join(args.fuchsia_src, "out", "default"),
]
fuchsia_src_map = f"./../..={args.fuchsia_src}"

# Load debug symbols for the test binary and automatically attach
if args.test is not None:
Expand All @@ -883,7 +893,28 @@ def debug(self, args):
test_name,
)

# The fake-test-src-base directory maps to the suite directory
# e.g. tests/ui/foo.rs has a path of rust/fake-test-src-base/foo.rs
fake_test_src_base = os.path.join(
args.rust_src,
"fake-test-src-base",
)
real_test_src_base = os.path.join(
args.rust_src,
"tests",
args.test.split(os.path.sep)[0],
)
test_src_map = f"{fake_test_src_base}={real_test_src_base}"

with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f:
print(f"set source-map += {test_src_map}", file=f)

if rust_src_map is not None:
print(f"set source-map += {rust_src_map}", file=f)

if fuchsia_src_map is not None:
print(f"set source-map += {fuchsia_src_map}", file=f)

print(f"attach {test_name[:31]}", file=f)

command += [
Expand All @@ -900,6 +931,20 @@ def debug(self, args):
# Connect to the running emulator with zxdb
subprocess.run(command, env=self.ffx_cmd_env(), check=False)

def syslog(self, args):
subprocess.run(
[
self.tool_path("ffx"),
"--config",
self.ffx_user_config_path(),
"log",
"--since",
"now",
],
env=self.ffx_cmd_env(),
check=False,
)


def start(args):
test_env = TestEnvironment.from_args(args)
Expand Down Expand Up @@ -933,6 +978,12 @@ def debug(args):
return 0


def syslog(args):
test_env = TestEnvironment.read_from_file()
test_env.syslog(args)
return 0


def main():
parser = argparse.ArgumentParser()

Expand Down Expand Up @@ -1028,6 +1079,11 @@ def print_help(args):
)
debug_parser.set_defaults(func=debug)

syslog_parser = subparsers.add_parser(
"syslog", help="prints the device syslog"
)
syslog_parser.set_defaults(func=syslog)

args = parser.parse_args()
return args.func(args)

Expand Down
94 changes: 80 additions & 14 deletions src/doc/rustc/src/platform-support/fuchsia.md
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,9 @@ Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source
for the steps to build locally.

You'll also need to download a copy of the Fuchsia SDK. The current minimum
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).
supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version].

[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89

Fuchsia's test runner interacts with the Fuchsia emulator and is located at
`src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our
Expand All @@ -697,7 +699,7 @@ test environment with:
src/ci/docker/scripts/fuchsia-test-runner.py start
--rust ${RUST_SRC_PATH}/install
--sdk ${SDK_PATH}
--target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
--target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
```

Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
Expand All @@ -717,17 +719,11 @@ run the full `tests/ui` test suite:
--target x86_64-unknown-fuchsia \
--run=always --jobs 1 \
--test-args --target-rustcflags \
--test-args -L \
--test-args --target-rustcflags \
--test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
--test-args --target-rustcflags \
--test-args -L \
--test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \
--test-args --target-rustcflags \
--test-args ${SDK_PATH}/arch/{x64|arm64}/lib \
--test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \
--test-args --target-rustcflags \
--test-args -Cpanic=abort \
--test-args --target-rustcflags \
--test-args -Zpanic_abort_tests \
--test-args -Clink-arg=--undefined-version \
--test-args --remote-test-client \
--test-args src/ci/docker/scripts/fuchsia-test-runner.py \
)
Expand All @@ -736,7 +732,18 @@ run the full `tests/ui` test suite:
*Note: The test suite cannot be run in parallel at the moment, so `x.py`
must be run with `--jobs 1` to ensure only one test runs at a time.*

When finished, the test runner can be used to stop the test environment:
By default, `x.py` compiles test binaries with `panic=unwind`. If you built your
Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test
binaries with `panic=abort` as well:

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

When finished testing, the test runner can be used to stop the test environment:

```sh
src/ci/docker/scripts/fuchsia-test-runner.py stop
Expand Down Expand Up @@ -764,8 +771,9 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
* `--symbol-path` gets required symbol paths, which are
necessary for stepping through your program.

The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can
display Rust and/or Fuchsia source code in your debugging session.
The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)"
section describes how you can display Rust and/or Fuchsia source code in your
debugging session.

### Using `zxdb`

Expand Down Expand Up @@ -866,6 +874,64 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \
Linking to a Fuchsia checkout can help with debugging Fuchsia libraries,
such as [fdio].

### Debugging the compiler test suite

Debugging the compiler test suite requires some special configuration:

First, we have to properly configure zxdb so it will be able to find debug
symbols and source information for our test. The test runner can do this for us
with:

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

where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`).

This will start a zxdb session that is properly configured for the specific test
being run. All three arguments are optional, so you can omit `--fuchsia-src` if
you don't have it downloaded. Now is a good time to set any desired breakpoints,
like `b main`.

Next, we have to tell `x.py` not to optimize or strip debug symbols from our
test suite binaries. We can do this by passing some new arguments to `rustc`
through our `x.py` invocation. The full invocation is:

```sh
( \
source config-env.sh && \
./x.py \
--config config.toml \
--stage=2 \
test tests/${TEST} \
--target x86_64-unknown-fuchsia \
--run=always --jobs 1 \
--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 \
)
```

*If you built your Rust toolchain with `panic=abort`, make sure to include the
previous flags so your test binaries are also compiled with `panic=abort`.*

Upon running this command, the test suite binary will be run and zxdb will
attach and load any relevant debug symbols.

[Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json
[Fuchsia]: https://fuchsia.dev/
[source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build
Expand Down

0 comments on commit 6e7902b

Please sign in to comment.