Files
visor/tools/build_cover.sh

96 lines
3.4 KiB
Bash
Executable File

#!/bin/bash
# Copyright 2025 The gVisor Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -x -e -o pipefail
dst=$(realpath "$1")
gopath_zip="$2"
go_mod="$3"
go_sum="$4"
runsc_main_go="$5"
golang_patch=$(realpath "$6")
race="$7"
mkdir .gocache
GOMODCACHE="$(pwd)/.gocache"
GOCACHE="$(pwd)/.gocache"
export GOMODCACHE GOCACHE
(
# The gVisor code coverage implementation uses internal packages. More details
# can be found here: https://github.com/golang/go/issues/76098.
go_version=1.26.3
go_base_url="https://dl.google.com/go/go${go_version}"
arch="$(uname -m)"
case "$arch" in
x86_64) go_arch="amd64" ;;
aarch64) go_arch="arm64" ;;
*) echo "Unsupported architecture: $arch" >&2; exit 1 ;;
esac
mkdir go-bootstrap
curl -fsSL "${go_base_url}.linux-${go_arch}.tar.gz" | tar -xz -C go-bootstrap
GOROOT_BOOTSTRAP="$(pwd)/go-bootstrap/go"
export GOROOT_BOOTSTRAP
curl -fsSL "${go_base_url}.src.tar.gz" | tar -xz
cd go
patch -p1 < "$golang_patch"
cd src
./make.bash
)
goroot_dir="$(pwd)/go"
go_tool="$goroot_dir/bin/go"
gvisor_gopath="gopath"
unzip -q "$gopath_zip" -d "$gvisor_gopath"
cp "$go_mod" "$go_sum" "$gvisor_gopath/src/gvisor.dev/gvisor/"
mkdir -p "$gvisor_gopath/src/gvisor.dev/gvisor/runsc"
cp "$runsc_main_go" "$gvisor_gopath/src/gvisor.dev/gvisor/runsc/main.go"
cd "$gvisor_gopath/src/gvisor.dev/gvisor/"
export GOROOT="$goroot_dir"
go_opts=""
go_tags="kcov,opensource"
if [[ "$race" = true ]]; then
go_opts="-race"
go_tags="$go_tags,lockdep"
else
# runsc has to be a self-contained binary to be able to run it in a minimal
# mount namespace.
export CGO_ENABLED=0
fi
# sleep, sync, syncevent use go:norace, which is not respected by coverage
# instrumentation. Race builds will be instrumented with atomic coverage (using
# sync/atomic.AddInt32), which will not work. We may be able to re-enable
# coverage on them when https://golang.org/issue/43007 is resolved.
# bpf is excluded because `bpf.Optimize` runs at sandbox startup and is a
# very expensive loop that restarts on every change.
# Under -covermode=atomic each of those blocks does a sync/atomic counter
# increment, and in a race build every one of those atomics additionally goes
# through the race detector on top, which compounds the issue and can make it
# take 10s of seconds for a codepath that is in practive never exercised on
# real ssndboxes, because seccomp filters are precompiled there. The only
# reason this runs at startup at all is because the presence of
# instrumentation itself changes the set of required seccomp filters, and we
# don't want to precompile the BPF instruction for those into the real runsc
# binary, so it is forced to run from scratch.
gopkgs=$("$go_tool" list ./... | grep -E -v 'pkg/sentry/platform|pkg/ring0|pkg/coverage|pkg/sleep|pkg/sync|pkg/syncevent|pkg/bpf' | paste -sd,)
"$go_tool" build --tags "$go_tags" $go_opts -cover -coverpkg="$gopkgs" -covermode=atomic -o "$dst" runsc/main.go