Skip to content

Commit c41e46f

Browse files
authored
Rust coverage report (for Suricata) (#4697)
* Rust coverage test * Workaround to get rust coverage for Suricata
1 parent 96ae2ed commit c41e46f

File tree

13 files changed

+134
-8
lines changed

13 files changed

+134
-8
lines changed

infra/base-images/base-builder/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly --profil
9090
RUN cargo install cargo-fuzz
9191
# Needed to recompile rust std library for MSAN
9292
RUN rustup component add rust-src --toolchain nightly
93+
# Set up custom environment variable for source code copy for coverage reports
94+
ENV OSSFUZZ_RUSTPATH /rust
9395

9496
# Install Bazel through Bazelisk, which automatically fetches the latest Bazel version.
9597
ENV BAZELISK_VERSION 1.7.4
@@ -185,7 +187,7 @@ RUN cd $SRC && \
185187
tar -xzv --strip-components=1 -f $SRC/oss-fuzz.tar.gz && \
186188
rm -rf examples $SRC/oss-fuzz.tar.gz
187189

188-
COPY compile compile_afl compile_dataflow compile_libfuzzer compile_honggfuzz \
190+
COPY cargo compile compile_afl compile_dataflow compile_libfuzzer compile_honggfuzz \
189191
compile_go_fuzzer precompile_honggfuzz precompile_afl debug_afl srcmap \
190192
write_labels.py /usr/local/bin/
191193

infra/base-images/base-builder/cargo

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash -eu
2+
# Copyright 2020 Google Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
# This is a wrapper around calling cargo
17+
# This just expands RUSTFLAGS in case of a coverage build
18+
# We need this until https://github.com/rust-lang/cargo/issues/5450 is merged
19+
# because cargo uses relative paths for the current crate
20+
# and absolute paths for its dependencies
21+
#
22+
################################################################################
23+
24+
export PATH="/rust/bin:$PATH"
25+
26+
if [ "$SANITIZER" = "coverage" ] && [ $1 = "build" ]
27+
then
28+
crate_src_abspath=`cargo metadata --no-deps --format-version 1 | jq -r '.workspace_root'`
29+
export RUSTFLAGS="$RUSTFLAGS --remap-path-prefix src=$crate_src_abspath/src"
30+
fi
31+
32+
if [ "$SANITIZER" = "coverage" ] && [ $1 = "fuzz" ]
33+
then
34+
fuzz_src_abspath=`pwd`
35+
export RUSTFLAGS="$RUSTFLAGS --remap-path-prefix fuzz_targets=$fuzz_src_abspath/fuzz_targets"
36+
# hack to turn cargo fuzz build into cargo build so as to get coverage
37+
# cargo fuzz adds "--target" "x86_64-unknown-linux-gnu"
38+
(
39+
# go into fuzz directory if not already the case
40+
cd fuzz || true
41+
# do not optimize with --release, leading to Malformed instrumentation profile data
42+
cargo build --bins
43+
# copies the build output in the expected target directory
44+
cd target
45+
mkdir -p x86_64-unknown-linux-gnu/release
46+
cp -r debug/* x86_64-unknown-linux-gnu/release/
47+
)
48+
exit 0
49+
fi
50+
51+
cargo "$@"

infra/base-images/base-builder/compile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ if [ "$SANITIZER" != "undefined" ] && [ "$SANITIZER" != "coverage" ] && [ "$ARCH
103103
else
104104
export RUSTFLAGS="--cfg fuzzing -Cdebuginfo=1 -Cforce-frame-pointers"
105105
fi
106+
if [ "$SANITIZER" = "coverage" ]
107+
then
108+
# link to C++ from comment in f5098035eb1a14aa966c8651d88ea3d64323823d
109+
export RUSTFLAGS="$RUSTFLAGS -Zinstrument-coverage -C link-arg=-lc++"
110+
fi
106111

107112
# Add Rust libfuzzer flags.
108113
# See https://github.com/rust-fuzz/libfuzzer/blob/master/build.rs#L12.
@@ -145,7 +150,7 @@ BUILD_CMD="bash -eux $SRC/build.sh"
145150

146151
# We need to preserve source code files for generating a code coverage report.
147152
# We need exact files that were compiled, so copy both $SRC and $WORK dirs.
148-
COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH $OUT"
153+
COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH $OSSFUZZ_RUSTPATH $OUT"
149154

150155
if [ "${BUILD_UID-0}" -ne "0" ]; then
151156
adduser -u $BUILD_UID --disabled-password --gecos '' builder

infra/base-images/base-clang/checkout_build_install_llvm.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
# 2).
2121
NPROC=$(expr $(nproc) / 2)
2222

23-
LLVM_DEP_PACKAGES="build-essential make cmake ninja-build git python3 g++-multilib binutils-dev"
23+
# zlib1g-dev is needed for llvm-profdata to handle coverage data from rust compiler
24+
LLVM_DEP_PACKAGES="build-essential make cmake ninja-build git python3 g++-multilib binutils-dev zlib1g-dev"
2425
apt-get install -y $LLVM_DEP_PACKAGES --no-install-recommends
2526

2627
# Checkout

infra/base-images/base-runner/Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ RUN apt-get update && apt-get install -y \
6868
python3 \
6969
python3-pip \
7070
wget \
71+
curl \
7172
zip
7273

7374
RUN git clone https://chromium.googlesource.com/chromium/src/tools/code_coverage /opt/code_coverage && \
@@ -83,6 +84,13 @@ ENV UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:silence_unsigned_overflow=
8384
ENV FUZZER_ARGS="-rss_limit_mb=2560 -timeout=25"
8485
ENV AFL_FUZZER_ARGS="-m none"
8586

87+
# Install rustfilt for symbol demangling.
88+
ENV CARGO_HOME=/rust
89+
ENV RUSTUP_HOME=/rust/rustup
90+
ENV PATH=$PATH:/rust/bin
91+
RUN curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=nightly
92+
RUN cargo install rustfilt
93+
8694
# Install OpenJDK 15 and trim its size by removing unused components.
8795
ENV JAVA_HOME=/usr/lib/jvm/java-15-openjdk-amd64
8896
ENV JVM_LD_LIBRARY_PATH=$JAVA_HOME/lib/server
@@ -103,6 +111,7 @@ COPY bad_build_check \
103111
dataflow_tracer.py \
104112
download_corpus \
105113
minijail0 \
114+
rcfilt \
106115
reproduce \
107116
run_fuzzer \
108117
run_minijail \

infra/base-images/base-runner/coverage

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ else
193193

194194
# Generate HTML report.
195195
llvm-cov show -format=html -output-dir=$REPORT_ROOT_DIR \
196-
-Xdemangler c++filt -Xdemangler -n $LLVM_COV_ARGS
196+
-Xdemangler rcfilt $LLVM_COV_ARGS
197197

198198
# Export coverage summary in JSON format.
199199
llvm-cov export -summary-only $LLVM_COV_ARGS > $SUMMARY_FILE

infra/base-images/base-runner/rcfilt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash -u
2+
# Copyright 2020 Google Inc.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
# Symbol demangling for both C++ and Rust
17+
#
18+
################################################################################
19+
20+
# simply pipe
21+
rustfilt | c++filt -n

infra/build/functions/build_and_run_coverage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
UPLOAD_URL_FORMAT = 'gs://' + COVERAGE_BUCKET_NAME + '/{project}/{type}/{date}'
4949

5050
# Languages from project.yaml that have code coverage support.
51-
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
51+
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
5252

5353

5454
def usage():

infra/ci/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
DEFAULT_SANITIZERS = ['address', 'undefined']
3333

3434
# Languages from project.yaml that have code coverage support.
35-
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
35+
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
3636

3737

3838
def get_changed_files_output():

infra/helper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
PROJECT_LANGUAGE_REGEX = re.compile(r'\s*language\s*:\s*([^\s]+)')
6060

6161
# Languages from project.yaml that have code coverage support.
62-
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go']
62+
LANGUAGES_WITH_COVERAGE_SUPPORT = ['c', 'c++', 'go', 'rust']
6363

6464
# pylint: disable=too-many-lines
6565

0 commit comments

Comments
 (0)