#!/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