t / valgrind / analyze.shon commit Merge branch 'mm/gc-safety-doc' (979b82f)
   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
   8output=
   9count=0
  10total_count=0
  11missing_message=
  12new_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
  17start_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
  31finish_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
  49output_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
  77handle_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
 122for test_script in "$TEST_OUTPUT_DIRECTORY"/test-results/*.out
 123do
 124        handle_one $test_script
 125done
 126
 127output_all