3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#!/bin/bash
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# Run Valgrind, condensing logged reports into an exit code.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# Copyright (C) 2014 Red Hat
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# This program is free software; you can redistribute it and/or modify
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# it under the terms of the GNU General Public License as published by
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# the Free Software Foundation; either version 3 of the License, or
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# (at your option) any later version.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# This program is distributed in the hope that it will be useful,
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# but WITHOUT ANY WARRANTY; without even the implied warranty of
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# GNU General Public License for more details.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov#
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# You should have received a copy of the GNU General Public License
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# along with this program. If not, see <http://www.gnu.org/licenses/>.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovset -o nounset -o pipefail -o errexit
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovshopt -s extglob
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfunction usage()
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov{
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov cat <<EOF
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai KondrashovUsage: `basename "$0"` ERROR_EXITCODE [PATH_PATTERN...] [-- VALGRIND_ARG...]
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai KondrashovRun Valgrind, condensing logged reports into an exit code.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai KondrashovArguments:
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov ERROR_EXITCODE An exit code to return if at least one error is found in
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov Valgrind log files.
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov PATH_PATTERN An extended glob pattern matching the (original) path to
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov the program to execute under Valgrind. If the program path
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov doesn't match any patterns, the program is executed
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov directly, without Valgrind. Without patterns any program
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov path matches.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov VALGRIND_ARG An argument to pass to Valgrind after the arguments
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov specified by `basename "$0"`.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai KondrashovThe first non-option VALGRIND_ARG, or the first VALGRIND_ARG after a "--",
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovwill be considered the path to the program to execute under Valgrind and will
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovbe used in naming Valgrind log files as such:
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov PROGRAM_NAME.PID.valgrind.log
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovwhere PROGRAM_NAME is the filename portion of the program path and PID is the
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovexecuted process ID. If the last directory of the program path is ".libs" and
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovthe filename begins with "lt-", both are removed to match the name of libtool
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfrontend script. All files matching PROGRAM_NAME.*.valgrind.log are removed
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovbefore invoking Valgrind.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai KondrashovIf an error is found in Valgrind log files, ERROR_EXITCODE is returned,
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovotherwise Valgrind exit code is returned.
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai KondrashovEOF
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov}
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovif [[ $# == 0 ]]; then
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov echo "Invalid number of arguments." >&2
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov usage >&2
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov exit 1
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare error_exitcode="$1"; shift
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare -a path_pattern_list=()
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare arg
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovdeclare collecting_argv
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovdeclare -a program_argv=()
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare program_path
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovdeclare program_name
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare path_pattern
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare match
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdeclare status=0
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# Extract path patterns
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovwhile [[ $# != 0 ]]; do
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov arg="$1"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov shift
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov if [[ "$arg" == "--" ]]; then
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov break
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov else
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov path_pattern_list+=("$arg")
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov fi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdone
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov# Find program argv list in Valgrind arguments
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovcollecting_argv=false
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfor arg in "$@"; do
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov if ! "$collecting_argv" && [[ "$arg" == "--" ]]; then
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov collecting_argv=true
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov elif "$collecting_argv" || [[ "$arg" != -* ]]; then
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov collecting_argv=true
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov program_argv+=("$arg")
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov fi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovdone
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovif [[ ${#program_argv[@]} == 0 ]]; then
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov echo "Program path not specified." >&2
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov usage >&2
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov exit 1
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfi
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovprogram_path="${program_argv[0]}"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov# Match against path patterns, if any
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovif [[ ${#path_pattern_list[@]} == 0 ]]; then
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov match=true
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovelse
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov match=false
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov for path_pattern in "${path_pattern_list[@]}"; do
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov if [[ "$program_path" == $path_pattern ]]; then
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov match=true
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov fi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov done
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov# Run the program
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashovif $match; then
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov # Generate original path from libtool path
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov program_path=`sed -e 's/^\(.*\/\)\?\.libs\/lt-\([^\/]\+\)$/\1\2/' \
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov <<<"$program_path"`
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
96544fca522e66b4f69b4252854a5f672c96f9c4Nikolai Kondrashov program_name=`basename -- "$program_path"`
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
96544fca522e66b4f69b4252854a5f672c96f9c4Nikolai Kondrashov rm -f -- "$program_name".*.valgrind.log
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov valgrind --log-file="$program_name.%p.valgrind.log" "$@" || status=$?
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashov
96544fca522e66b4f69b4252854a5f672c96f9c4Nikolai Kondrashov if grep -q '^==[0-9]\+== *ERROR SUMMARY: *[1-9]' -- \
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov "$program_name".*.valgrind.log; then
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov exit "$error_exitcode"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov else
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov exit "$status"
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov fi
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovelse
5f4f0428c182a9e77d29b39f3749fce03643ac8dNikolai Kondrashov "${program_argv[@]}"
3ce85a5f5264e7118beb6524e120fd8b53a13da4Nikolai Kondrashovfi