#!/bin/sh
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Scape errors from the valgrind bots, reproduce them locally,
# save logs as regrind-TESTNAME.log, and display any errors found.
# Also save files regrind-failed.txt listing failed tests,
# and regrind-failed-map.txt showing which bot URLs have which failed tests
# (handy when filing bugs).
#
# Only scrapes linux layout bot at the moment.
# TODO: handle layout tests that don't have obvious path to test file
# TODO: extend script to handle more kinds of errors and more tests
# where the valgrind layout bot results live
LAYOUT_URL="http://build.chromium.org/p/chromium.memory.fyi/builders/Webkit%20Linux%20(valgrind%20layout)"
# how many builds back to check
LAYOUT_COUNT=250
# regexp to match valgrind errors
PATTERN="are definitely|uninitialised|Unhandled exception|\
Invalid read|Invalid write|Invalid free|Source and desti|Mismatched free|\
unaddressable byte|vex x86|the 'impossible' happened|\
valgrind:.*: Assertion.*failed|VALGRIND INTERNAL ERROR"
usage() {
echo "Usage: regrind.sh [--noscrape][--norepro][--keep]"
echo "--noscrape: don't scrape bots, just use old regrind-failed.txt"
echo "--norepro: don't reproduce locally"
echo "--keep: keep temp files"
exit 1
}
# Given a log on stdin, list all the tests that failed in that log.
layout_list_failed_tests() {
grep "Command:.*LayoutTests" |
sed 's/<.*>//' |
sed 's/.*LayoutTests/LayoutTests/' |
sort -u |
tr -d '\015'
}
# Generate a list of failed tests in regrind-failed.txt by scraping bot.
# Scrape most recent first, so if user interrupts, he is left with fresh-ish data.
scrape_layout() {
rm -f regrind-*.tmp* regrind-failed.txt regrind-failed-map.txt
touch regrind-failed.txt
# First, grab the number of the latest complete build.
wget -q -O regrind-builds.html "$LAYOUT_URL"
latest=`grep "<li><font .*" < regrind-builds.html | head -1 | sed 's/.*#//;s/<.*//'`
echo "Fetching $LAYOUT_COUNT logs from bot"
# Scrape the desired number of runs (150 is about one cycle)
first=`expr $latest - $LAYOUT_COUNT`
i=$latest
while test $i -ge $first
do
url="$LAYOUT_URL/builds/$i/steps/valgrind%20test:%20layout/logs/stdio"
wget -q -O regrind-$i.tmp "$url"
# Did any tests fail in this file?
layout_list_failed_tests < regrind-$i.tmp > regrind-$i.tmp.failed
if test -s regrind-$i.tmp.failed
then
# Yes. Log them to stdout,
echo "$url"
cat regrind-$i.tmp.failed
# to the table regrind-failed-map.txt,
cat regrind-$i.tmp.failed | sed "s,^,$url ," >> regrind-failed-map.txt
# and, if not already there, to regrind-failed.txt.
for test in `cat regrind-$i.tmp.failed`
do
fgrep "$test" regrind-failed.txt > /dev/null 2>&1 || echo "$test" >> regrind-failed.txt
done
else
rm regrind-$i.tmp.failed
fi
# Sleep 1/3 sec per fetch
case $i in
*[036]) sleep 1;;
esac
i=`expr $i - 1`
done
# Finally, munge the logs to identify tests that probably failed.
sh c.sh -l regrind-*.tmp > regrind-errfiles.txt
cat `cat regrind-errfiles.txt` | layout_list_failed_tests > regrind-failed.txt
}
# Run the tests identified in regrind-failed.txt locally under valgrind.
# Save logs in regrind-$TESTNAME.log.
repro_layout() {
echo Running `wc -l < regrind-failed.txt` layout tests.
for test in `cat regrind-failed.txt`
do
logname="`echo $test | tr / _`"
echo "sh tools/valgrind/valgrind_webkit_tests.sh $test"
sh tools/valgrind/valgrind_webkit_tests.sh "$test" > regrind-"$logname".log 2>&1
egrep "$PATTERN" < regrind-"$logname".log | sed 's/==.*==//'
done
}
do_repro=1
do_scrape=1
do_cleanup=1
while test ! -z "$1"
do
case "$1" in
--noscrape) do_scrape=0;;
--norepro) do_repro=0;;
--keep) do_cleanup=0;;
*) usage;;
esac
shift
done
echo "WARNING: This script is not supported and may be out of date"
if test $do_scrape = 0 && test $do_repro = 0
then
usage
fi
if test $do_scrape = 1
then
scrape_layout
fi
if test $do_repro = 1
then
repro_layout
fi
if test $do_cleanup = 1
then
rm -f regrind-errfiles.txt regrind-*.tmp*
fi