James Robinson | 646469d | 2014-10-03 15:33:28 -0700 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | # Scape errors from the valgrind bots, reproduce them locally, |
| 7 | # save logs as regrind-TESTNAME.log, and display any errors found. |
| 8 | # Also save files regrind-failed.txt listing failed tests, |
| 9 | # and regrind-failed-map.txt showing which bot URLs have which failed tests |
| 10 | # (handy when filing bugs). |
| 11 | # |
| 12 | # Only scrapes linux layout bot at the moment. |
| 13 | # TODO: handle layout tests that don't have obvious path to test file |
| 14 | # TODO: extend script to handle more kinds of errors and more tests |
| 15 | |
| 16 | # where the valgrind layout bot results live |
| 17 | LAYOUT_URL="http://build.chromium.org/p/chromium.memory.fyi/builders/Webkit%20Linux%20(valgrind%20layout)" |
| 18 | # how many builds back to check |
| 19 | LAYOUT_COUNT=250 |
| 20 | |
| 21 | # regexp to match valgrind errors |
| 22 | PATTERN="are definitely|uninitialised|Unhandled exception|\ |
| 23 | Invalid read|Invalid write|Invalid free|Source and desti|Mismatched free|\ |
| 24 | unaddressable byte|vex x86|the 'impossible' happened|\ |
| 25 | valgrind:.*: Assertion.*failed|VALGRIND INTERNAL ERROR" |
| 26 | |
| 27 | usage() { |
| 28 | echo "Usage: regrind.sh [--noscrape][--norepro][--keep]" |
| 29 | echo "--noscrape: don't scrape bots, just use old regrind-failed.txt" |
| 30 | echo "--norepro: don't reproduce locally" |
| 31 | echo "--keep: keep temp files" |
| 32 | exit 1 |
| 33 | } |
| 34 | |
| 35 | # Given a log on stdin, list all the tests that failed in that log. |
| 36 | layout_list_failed_tests() { |
| 37 | grep "Command:.*LayoutTests" | |
| 38 | sed 's/<.*>//' | |
| 39 | sed 's/.*LayoutTests/LayoutTests/' | |
| 40 | sort -u | |
| 41 | tr -d '\015' |
| 42 | } |
| 43 | |
| 44 | # Generate a list of failed tests in regrind-failed.txt by scraping bot. |
| 45 | # Scrape most recent first, so if user interrupts, he is left with fresh-ish data. |
| 46 | scrape_layout() { |
| 47 | rm -f regrind-*.tmp* regrind-failed.txt regrind-failed-map.txt |
| 48 | touch regrind-failed.txt |
| 49 | |
| 50 | # First, grab the number of the latest complete build. |
| 51 | wget -q -O regrind-builds.html "$LAYOUT_URL" |
| 52 | latest=`grep "<li><font .*" < regrind-builds.html | head -1 | sed 's/.*#//;s/<.*//'` |
| 53 | |
| 54 | echo "Fetching $LAYOUT_COUNT logs from bot" |
| 55 | # Scrape the desired number of runs (150 is about one cycle) |
| 56 | first=`expr $latest - $LAYOUT_COUNT` |
| 57 | i=$latest |
| 58 | while test $i -ge $first |
| 59 | do |
| 60 | url="$LAYOUT_URL/builds/$i/steps/valgrind%20test:%20layout/logs/stdio" |
| 61 | wget -q -O regrind-$i.tmp "$url" |
| 62 | # Did any tests fail in this file? |
| 63 | layout_list_failed_tests < regrind-$i.tmp > regrind-$i.tmp.failed |
| 64 | if test -s regrind-$i.tmp.failed |
| 65 | then |
| 66 | # Yes. Log them to stdout, |
| 67 | echo "$url" |
| 68 | cat regrind-$i.tmp.failed |
| 69 | # to the table regrind-failed-map.txt, |
| 70 | cat regrind-$i.tmp.failed | sed "s,^,$url ," >> regrind-failed-map.txt |
| 71 | # and, if not already there, to regrind-failed.txt. |
| 72 | for test in `cat regrind-$i.tmp.failed` |
| 73 | do |
| 74 | fgrep "$test" regrind-failed.txt > /dev/null 2>&1 || echo "$test" >> regrind-failed.txt |
| 75 | done |
| 76 | else |
| 77 | rm regrind-$i.tmp.failed |
| 78 | fi |
| 79 | # Sleep 1/3 sec per fetch |
| 80 | case $i in |
| 81 | *[036]) sleep 1;; |
| 82 | esac |
| 83 | i=`expr $i - 1` |
| 84 | done |
| 85 | |
| 86 | # Finally, munge the logs to identify tests that probably failed. |
| 87 | sh c.sh -l regrind-*.tmp > regrind-errfiles.txt |
| 88 | cat `cat regrind-errfiles.txt` | layout_list_failed_tests > regrind-failed.txt |
| 89 | } |
| 90 | |
| 91 | # Run the tests identified in regrind-failed.txt locally under valgrind. |
| 92 | # Save logs in regrind-$TESTNAME.log. |
| 93 | repro_layout() { |
| 94 | echo Running `wc -l < regrind-failed.txt` layout tests. |
| 95 | for test in `cat regrind-failed.txt` |
| 96 | do |
| 97 | logname="`echo $test | tr / _`" |
| 98 | echo "sh tools/valgrind/valgrind_webkit_tests.sh $test" |
| 99 | sh tools/valgrind/valgrind_webkit_tests.sh "$test" > regrind-"$logname".log 2>&1 |
| 100 | egrep "$PATTERN" < regrind-"$logname".log | sed 's/==.*==//' |
| 101 | done |
| 102 | } |
| 103 | |
| 104 | do_repro=1 |
| 105 | do_scrape=1 |
| 106 | do_cleanup=1 |
| 107 | while test ! -z "$1" |
| 108 | do |
| 109 | case "$1" in |
| 110 | --noscrape) do_scrape=0;; |
| 111 | --norepro) do_repro=0;; |
| 112 | --keep) do_cleanup=0;; |
| 113 | *) usage;; |
| 114 | esac |
| 115 | shift |
| 116 | done |
| 117 | |
| 118 | echo "WARNING: This script is not supported and may be out of date" |
| 119 | |
| 120 | if test $do_scrape = 0 && test $do_repro = 0 |
| 121 | then |
| 122 | usage |
| 123 | fi |
| 124 | |
| 125 | if test $do_scrape = 1 |
| 126 | then |
| 127 | scrape_layout |
| 128 | fi |
| 129 | |
| 130 | if test $do_repro = 1 |
| 131 | then |
| 132 | repro_layout |
| 133 | fi |
| 134 | |
| 135 | if test $do_cleanup = 1 |
| 136 | then |
| 137 | rm -f regrind-errfiles.txt regrind-*.tmp* |
| 138 | fi |