184 lines
6.6 KiB
Bash
Executable file
184 lines
6.6 KiB
Bash
Executable file
#!/bin/bash -ex
|
|
|
|
function usage() {
|
|
echo "Usage: $0 [--project <js|browser>] <workspace-dir> flags..."
|
|
echo "flags are treated the same way as a commit message would be"
|
|
echo "(as in, they are scanned for directives just like a try: ... line)"
|
|
}
|
|
|
|
PROJECT=js
|
|
WORKSPACE=
|
|
while [[ $# -gt 0 ]]; do
|
|
if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then
|
|
usage
|
|
exit 0
|
|
elif [[ "$1" == "--project" ]]; then
|
|
shift
|
|
PROJECT="$1"
|
|
shift
|
|
elif [[ "$1" == "--no-tooltool" ]]; then
|
|
shift
|
|
elif [[ -z "$WORKSPACE" ]]; then
|
|
WORKSPACE=$( cd "$1" && pwd )
|
|
shift
|
|
break
|
|
fi
|
|
done
|
|
|
|
function check_commit_msg () {
|
|
( set +e;
|
|
if [[ -n "$AUTOMATION" ]]; then
|
|
hg --cwd "$GECKO_PATH" log -r. --template '{desc}\n' | grep -F -q -- "$1"
|
|
else
|
|
echo -- "$SCRIPT_FLAGS" | grep -F -q -- "$1"
|
|
fi
|
|
)
|
|
}
|
|
|
|
if check_commit_msg "--dep"; then
|
|
HAZ_DEP=1
|
|
fi
|
|
|
|
SCRIPT_FLAGS=$*
|
|
|
|
ANALYSIS_DIR="$WORKSPACE/haz-$PROJECT"
|
|
|
|
# Ensure all the scripts in this dir are on the path....
|
|
DIRNAME=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
|
PATH=$DIRNAME:$PATH
|
|
|
|
# Use GECKO_BASE_REPOSITORY as a signal for whether we are running in automation.
|
|
export AUTOMATION=${GECKO_BASE_REPOSITORY:+1}
|
|
|
|
: "${GECKO_PATH:="$DIRNAME"/../../..}"
|
|
|
|
if ! [ -d "$GECKO_PATH" ]; then
|
|
echo "GECKO_PATH must be set to a directory containing a gecko source checkout" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Directory to hold the compiled JS shell that will run the analysis.
|
|
HAZARD_SHELL_OBJDIR=$WORKSPACE/obj-haz-shell
|
|
|
|
export NO_MERCURIAL_SETUP_CHECK=1
|
|
|
|
if [[ "$PROJECT" = "browser" ]]; then (
|
|
cd "$WORKSPACE"
|
|
set "$WORKSPACE"
|
|
# Mozbuild config:
|
|
export MOZBUILD_STATE_PATH=$WORKSPACE/mozbuild/
|
|
# Create .mozbuild so mach doesn't complain about this
|
|
mkdir -p "$MOZBUILD_STATE_PATH"
|
|
) fi
|
|
|
|
# Build the shell
|
|
export HAZARD_SHELL_OBJDIR # This will be picked up by mozconfig.haz_shell.
|
|
$GECKO_PATH/mach hazards build-shell
|
|
|
|
# Run a self-test
|
|
$GECKO_PATH/mach hazards self-test --shell-objdir="$HAZARD_SHELL_OBJDIR"
|
|
|
|
# Artifacts folder is outside of the cache.
|
|
mkdir -p "$HOME"/artifacts/ || true
|
|
|
|
function grab_artifacts () {
|
|
local artifacts
|
|
artifacts="$HOME/artifacts"
|
|
|
|
[ -d "$ANALYSIS_DIR" ] && (
|
|
cd "$ANALYSIS_DIR"
|
|
ls -lah
|
|
|
|
# Do not error out if no files found
|
|
shopt -s nullglob
|
|
set +e
|
|
local important
|
|
important=(refs.txt unnecessary.txt hazards.txt gcFunctions.txt allFunctions.txt heapWriteHazards.txt rootingHazards.json hazards.html)
|
|
|
|
# Bundle up the less important but still useful intermediate outputs,
|
|
# just to cut down on the clutter in treeherder's Job Details pane.
|
|
tar -acvf "${artifacts}/hazardIntermediates.tar.xz" --exclude-from <(IFS=$'\n'; echo "${important[*]}") *.txt *.lst build_xgill.log
|
|
|
|
# Upload the important outputs individually, so that they will be
|
|
# visible in Job Details and accessible to automated jobs.
|
|
for f in "${important[@]}"; do
|
|
gzip -9 -c "$f" > "${artifacts}/$f.gz"
|
|
done
|
|
|
|
# Check whether the user requested .xdb file upload in the top commit comment
|
|
if check_commit_msg "--upload-xdbs"; then
|
|
HAZ_UPLOAD_XDBS=1
|
|
fi
|
|
|
|
if [ -n "$HAZ_UPLOAD_XDBS" ]; then
|
|
for f in *.xdb; do
|
|
xz -c "$f" > "${artifacts}/$f.bz2"
|
|
done
|
|
fi
|
|
)
|
|
}
|
|
|
|
function check_hazards () {
|
|
(
|
|
set +e
|
|
NUM_HAZARDS=$(grep -c 'Function.*has unrooted.*live across GC call' "$1"/hazards.txt)
|
|
NUM_UNSAFE=$(grep -c '^Function.*takes unsafe address of unrooted' "$1"/refs.txt)
|
|
NUM_UNNECESSARY=$(grep -c '^Function.* has unnecessary root' "$1"/unnecessary.txt)
|
|
NUM_DROPPED=$(grep -c '^Dropped CFG' "$1"/build_xgill.log)
|
|
NUM_WRITE_HAZARDS=$(perl -lne 'print $1 if m!found (\d+)/\d+ allowed errors!' "$1"/heapWriteHazards.txt)
|
|
NUM_MISSING=$(grep -c '^Function.*expected hazard.*but none were found' "$1"/hazards.txt)
|
|
|
|
set +x
|
|
echo "TinderboxPrint: rooting hazards<br/>$NUM_HAZARDS"
|
|
echo "TinderboxPrint: (unsafe references to unrooted GC pointers)<br/>$NUM_UNSAFE"
|
|
echo "TinderboxPrint: (unnecessary roots)<br/>$NUM_UNNECESSARY"
|
|
echo "TinderboxPrint: missing expected hazards<br/>$NUM_MISSING"
|
|
echo "TinderboxPrint: heap write hazards<br/>$NUM_WRITE_HAZARDS"
|
|
|
|
# Display errors in a way that will get picked up by the taskcluster scraper.
|
|
perl -lne 'print "TEST-UNEXPECTED-FAIL | hazards | $1 $2" if /^Function.* has (unrooted .*live across GC call).* (at .*)$/' "$1"/hazards.txt
|
|
|
|
exit_status=0
|
|
|
|
if [ $NUM_HAZARDS -gt 0 ]; then
|
|
echo "TEST-UNEXPECTED-FAIL | hazards | $NUM_HAZARDS rooting hazards detected" >&2
|
|
echo "TinderboxPrint: documentation<br/><a href='https://firefox-source-docs.mozilla.org/js/HazardAnalysis/#diagnosing-a-rooting-hazards-failure'>static rooting hazard analysis failures</a>, visit \"Inspect Task\" link for hazard details"
|
|
exit_status=1
|
|
fi
|
|
|
|
if [ $NUM_MISSING -gt 0 ]; then
|
|
echo "TEST-UNEXPECTED-FAIL | hazards | $NUM_MISSING expected hazards went undetected" >&2
|
|
echo "TinderboxPrint: documentation<br/><a href='https://firefox-source-docs.mozilla.org/js/HazardAnalysis/#diagnosing-a-rooting-hazards-failure'>static rooting hazard analysis failures</a>, visit \"Inspect Task\" link for hazard details"
|
|
exit_status=1
|
|
fi
|
|
|
|
NUM_ALLOWED_WRITE_HAZARDS=0
|
|
if [ $NUM_WRITE_HAZARDS -gt $NUM_ALLOWED_WRITE_HAZARDS ]; then
|
|
echo "TEST-UNEXPECTED-FAIL | heap-write-hazards | $NUM_WRITE_HAZARDS heap write hazards detected out of $NUM_ALLOWED_WRITE_HAZARDS allowed" >&2
|
|
echo "TinderboxPrint: documentation<br/><a href='https://firefox-source-docs.mozilla.org/js/HazardAnalysis/#diagnosing-a-heap-write-hazard-failure'>heap write hazard analysis failures</a>, visit \"Inspect Task\" link for hazard details"
|
|
exit_status = 1
|
|
fi
|
|
|
|
if [ $NUM_DROPPED -gt 0 ]; then
|
|
echo "TEST-UNEXPECTED-FAIL | hazards | $NUM_DROPPED CFGs dropped" >&2
|
|
echo "TinderboxPrint: sixgill unable to handle constructs<br/>$NUM_DROPPED"
|
|
exit_status=1
|
|
fi
|
|
|
|
if [ $exit_status -ne 0 ]; then
|
|
exit $exit_status
|
|
fi
|
|
)
|
|
}
|
|
|
|
trap grab_artifacts EXIT
|
|
|
|
# Gather the information from the source tree by compiling it.
|
|
$GECKO_PATH/mach hazards gather --project=$PROJECT --work-dir="$ANALYSIS_DIR"
|
|
|
|
# Analyze the collected information.
|
|
$GECKO_PATH/mach hazards analyze --project=$PROJECT --shell-objdir="$HAZARD_SHELL_OBJDIR" --work-dir="$ANALYSIS_DIR"
|
|
|
|
check_hazards "$ANALYSIS_DIR"
|
|
|
|
################################### script end ###################################
|