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