| 1 | #!/bin/sh |
| 2 | |
| 3 | # Get TEST_OUTPUT_DIRECTORY from GIT-BUILD-OPTIONS if it's there... |
| 4 | . "$(dirname "$0")/../../GIT-BUILD-OPTIONS" |
| 5 | # ... otherwise set it to the default value. |
| 6 | : ${TEST_OUTPUT_DIRECTORY=$(dirname "$0")/..} |
| 7 | |
| 8 | output= |
| 9 | count=0 |
| 10 | total_count=0 |
| 11 | missing_message= |
| 12 | new_line=' |
| 13 | ' |
| 14 | |
| 15 | # start outputting the current valgrind error in $out_prefix.++$count, |
| 16 | # and the test case which failed in the corresponding .message file |
| 17 | start_output () { |
| 18 | test -z "$output" || return |
| 19 | |
| 20 | # progress |
| 21 | total_count=$(($total_count+1)) |
| 22 | test -t 2 && printf "\rFound %d errors" $total_count >&2 |
| 23 | |
| 24 | count=$(($count+1)) |
| 25 | output=$out_prefix.$count |
| 26 | : > $output |
| 27 | |
| 28 | echo "*** $1 ***" > $output.message |
| 29 | } |
| 30 | |
| 31 | finish_output () { |
| 32 | test ! -z "$output" || return |
| 33 | output= |
| 34 | |
| 35 | # if a test case has more than one valgrind error, we need to |
| 36 | # copy the last .message file to the previous errors |
| 37 | test -z "$missing_message" || { |
| 38 | while test $missing_message -lt $count |
| 39 | do |
| 40 | cp $out_prefix.$count.message \ |
| 41 | $out_prefix.$missing_message.message |
| 42 | missing_message=$(($missing_message+1)) |
| 43 | done |
| 44 | missing_message= |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | # group the valgrind errors by backtrace |
| 49 | output_all () { |
| 50 | last_line= |
| 51 | j=0 |
| 52 | i=1 |
| 53 | while test $i -le $count |
| 54 | do |
| 55 | # output <number> <backtrace-in-one-line> |
| 56 | echo "$i $(tr '\n' ' ' < $out_prefix.$i)" |
| 57 | i=$(($i+1)) |
| 58 | done | |
| 59 | sort -t ' ' -k 2 | # order by <backtrace-in-one-line> |
| 60 | while read number line |
| 61 | do |
| 62 | # find duplicates, do not output backtrace twice |
| 63 | if test "$line" != "$last_line" |
| 64 | then |
| 65 | last_line=$line |
| 66 | j=$(($j+1)) |
| 67 | printf "\nValgrind error $j:\n\n" |
| 68 | cat $out_prefix.$number |
| 69 | printf "\nfound in:\n" |
| 70 | fi |
| 71 | # print the test case where this came from |
| 72 | printf "\n" |
| 73 | cat $out_prefix.$number.message |
| 74 | done |
| 75 | } |
| 76 | |
| 77 | handle_one () { |
| 78 | OLDIFS=$IFS |
| 79 | IFS="$new_line" |
| 80 | while read line |
| 81 | do |
| 82 | case "$line" in |
| 83 | # backtrace, possibly a new one |
| 84 | ==[0-9]*) |
| 85 | |
| 86 | # Does the current valgrind error have a message yet? |
| 87 | case "$output" in |
| 88 | *.message) |
| 89 | test -z "$missing_message" && |
| 90 | missing_message=$count |
| 91 | output= |
| 92 | esac |
| 93 | |
| 94 | start_output $(basename $1) |
| 95 | echo "$line" | |
| 96 | sed 's/==[0-9]*==/==valgrind==/' >> $output |
| 97 | ;; |
| 98 | # end of backtrace |
| 99 | '}') |
| 100 | test -z "$output" || { |
| 101 | echo "$line" >> $output |
| 102 | test $output = ${output%.message} && |
| 103 | output=$output.message |
| 104 | } |
| 105 | ;; |
| 106 | # end of test case |
| 107 | '') |
| 108 | finish_output |
| 109 | ;; |
| 110 | # normal line; if $output is set, print the line |
| 111 | *) |
| 112 | test -z "$output" || echo "$line" >> $output |
| 113 | ;; |
| 114 | esac |
| 115 | done < $1 |
| 116 | IFS=$OLDIFS |
| 117 | |
| 118 | # just to be safe |
| 119 | finish_output |
| 120 | } |
| 121 | |
| 122 | for test_script in "$TEST_OUTPUT_DIRECTORY"/test-results/*.out |
| 123 | do |
| 124 | handle_one $test_script |
| 125 | done |
| 126 | |
| 127 | output_all |