summaryrefslogtreecommitdiffstats
path: root/tools/valgrind/regrind.sh
blob: 557a6e8600e0d53ae30cdf6b7ba488d32f089560 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/bin/sh
# 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/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

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