Skip to content

Commit 98ffe9d

Browse files
authored
Merge pull request #1990 from DLR-AMR/1921-run-valgrind-check-in-ci-in-parallel
Improvement: Add possibility to use mpi with valgrind to check_valgrind scripts
2 parents a8ed5f0 + aa92df9 commit 98ffe9d

File tree

4 files changed

+77
-21
lines changed

4 files changed

+77
-21
lines changed

.github/workflows/tests_cmake_valgrind.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ jobs:
104104
- name: ninja install
105105
run: cd build && ninja install $MAKEFLAGS
106106
# Execute script that runs a Valgrind check for all test binaries.
107+
# We use 3 parallel processes to run the binaries in parallel with MPI.
107108
- name: Valgrind check
108-
run: cd scripts && bash ./check_all_test_binaries_valgrind.sh
109+
run: cd scripts && bash ./check_all_test_binaries_valgrind.sh --ntasks=3
109110

scripts/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ This script indents all t8code source files at once. This script should only be
3232

3333
#### find_all_source_files.sh
3434

35-
List all source files of t8code in the `src/` `example/` and `test/` subfolders.
35+
List all source files of t8code in the `src/`, `example/` and `test/` subfolders.
3636

3737
#### check_valgrind.sh
3838

39-
This script runs Valgrind on a binary path provided as a parameter with specified memory leak detection flags. The Valgrind output is parsed. As a second argument, you can provide a path to a suppression file that is used by Valgrind to suppress certain errors (e.g. [valgrind_suppressions_file](valgrind_suppressions_file.supp)).
39+
This script runs Valgrind on a binary path provided as a parameter with specified memory leak detection flags. The Valgrind output is parsed. Using `--supp=[FILE]`, you can provide a path to a suppression file that is used by Valgrind to suppress certain errors (e.g. [valgrind_suppressions_file](valgrind_suppressions_file.supp)). With `--ntasks=[NUMBER]`, you can provide the number of processes to use with mpi (default is 1).
4040

4141
#### find_all_test_binary_paths.sh
4242

@@ -46,7 +46,7 @@ The paths are relative paths assuming an execution from the test/ folder in the
4646
#### check_all_test_binaries_valgrind.sh
4747

4848
This script performs a valgrind check on each test binary found by [find_all_test_binary_paths.sh](find_all_test_binary_paths.sh).
49-
The valgrind check is done by [check_valgrind.sh](check_valgrind.sh). It is assumed that the build folder ../build/test/ with the correct test binaries exists.
49+
The valgrind check is done by [check_valgrind.sh](check_valgrind.sh). It is assumed that the build folder ../build/test/ with the correct test binaries exists. With `--ntasks=[NUMBER]`, you can provide the number of processes to use with mpi (default is 1).
5050

5151
## Others
5252

scripts/check_all_test_binaries_valgrind.sh

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,36 @@
2626
# The script returns 1 if an error is found and 0 otherwise.
2727
# This script must be executed from the scripts/ folder.
2828
# It is assumed that the build folder ../build/test/ with the correct test binaries exists.
29+
# With "--ntasks=[NUMBER]", you can provide the number of processes to use with MPI (default is 1).
2930
#
3031

32+
USAGE="\nUSAGE: This script executes valgrind in parallel on each test binary available. Use the syntax \n
33+
$0 --ntasks=[NUM_TASKS]\n
34+
Providing the number of parallel processes to use with MPI is optional.\n"
35+
36+
# Check if a number of processes is provided. If not, set to 1.
37+
num_procs=1
38+
for arg in "$@"; do
39+
if [[ "$arg" == --ntasks=* ]]; then
40+
ntasks_val="${arg#--ntasks=}"
41+
if [[ "$ntasks_val" =~ ^[0-9]+$ ]]; then
42+
num_procs="$ntasks_val"
43+
else
44+
echo "ERROR: --ntasks value '$ntasks_val' is not a valid number."
45+
echo -e "$USAGE"
46+
exit 1
47+
fi
48+
fi
49+
done
50+
3151
# Script must be executed from the scripts/ folder.
3252
if [ `basename $PWD` != scripts ]; then
3353
if [ -d scripts ]; then
3454
# The directory stack is automatically reset on script exit.
3555
pushd scripts/ > /dev/null
3656
else
3757
echo "ERROR: scripts/ directory not found."
58+
echo -e "$USAGE"
3859
exit 1
3960
fi
4061
fi
@@ -50,6 +71,7 @@ if [ -d ../build/test ]; then
5071
pushd ../build/test/ > /dev/null
5172
else
5273
echo "ERROR: Couldn't find a the directory ../build/test/."
74+
echo -e "$USAGE"
5375
exit 1
5476
fi
5577

@@ -59,9 +81,9 @@ valgrind_suppressions_file=../../scripts/valgrind_suppressions_file.supp
5981

6082
for bin_path in $test_bin_paths; do
6183
counter=$(( $counter + 1 ))
62-
echo "[$counter/$num_paths] Valgrind check of $bin_path..."
84+
echo -n "[$counter/$num_paths] "
6385
# Run check_valgrind script for each test binary.
64-
bash ../../scripts/check_valgrind.sh $bin_path $valgrind_suppressions_file 2>&1
86+
bash ../../scripts/check_valgrind.sh $bin_path --supp=$valgrind_suppressions_file --ntasks=$num_procs 2>&1
6587
status=$?
6688
# If status is not 0, an error occurred.
6789
if test $status -ne 0; then

scripts/check_valgrind.sh

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,18 @@
2323
#
2424
# This script runs Valgrind on an input binary paths with specified memory leak detection flags.
2525
# The Valgrind output is parsed. If any errors are found, they are printed and the script exits with a status of 1.
26-
# As a second argument, you can provide a path to a suppression file that is used by Valgrind to suppress certain errors.
26+
# If errors are found, the Valgrind output is kept in the file valgrind-output.log for further inspection.
27+
# Using "--supp=[FILE]", you can provide a path to a suppression file that is used by Valgrind to suppress certain errors.
28+
# With "--ntasks=[NUMBER]", you can provide the number of processes to use with MPI (default is 1).
2729
#
30+
USAGE="\nUSAGE: This script executes valgrind in parallel on a given input file. Use \n
31+
$0 [FILE] --supp=[SUPPRESSION_FILE] --ntasks=[NUM_TASKS]\n
32+
to run valgrind on FILE. Optionally you can provide a suppression file and the number of parallel processes to use with MPI.\n"
2833

2934
# Check that an argument is given and that the argument is a file.
3035
if [ ${1-x} = x ]; then
31-
echo ERROR: Need to provide a file as first argument.
36+
echo "ERROR: Need to provide a file as first argument."
37+
echo -e "$USAGE"
3238
exit 1
3339
fi
3440
if [ -f "$1" ]; then
@@ -39,14 +45,47 @@ else
3945
FILE="../$1"
4046
else
4147
echo "ERROR: Non existing file: $1"
48+
echo -e "$USAGE"
4249
exit 1
4350
fi
4451
fi
4552

53+
# Check if a suppression file is provided. If yes, add the flag to incorporate the Valgrind suppression file.
54+
VALGRIND_FLAGS=""
55+
for arg in "$@"; do
56+
if [[ "$arg" == --supp=* ]]; then
57+
supp_file="${arg#--supp=}"
58+
if [ -f "$supp_file" ]; then
59+
VALGRIND_FLAGS="${VALGRIND_FLAGS} --suppressions=${supp_file}"
60+
else
61+
echo "ERROR: Suppression file '$supp_file' does not exist."
62+
echo -e "$USAGE"
63+
exit 1
64+
fi
65+
fi
66+
done
67+
68+
# Check if a number of processes is provided. If not, set to 1.
69+
num_procs=1
70+
for arg in "$@"; do
71+
if [[ "$arg" == --ntasks=* ]]; then
72+
ntasks_val="${arg#--ntasks=}"
73+
if [[ "$ntasks_val" =~ ^[0-9]+$ ]]; then
74+
num_procs="$ntasks_val"
75+
else
76+
echo "ERROR: --ntasks value '$ntasks_val' is not a valid number."
77+
echo -e "$USAGE"
78+
exit 1
79+
fi
80+
fi
81+
done
82+
83+
echo "Valgrind check of ${FILE} using ${num_procs} processes..."
84+
4685
# Write valgrind output to variable OUTPUT_FILE.
4786
OUTPUT_FILE="valgrind-output.log"
4887
# Set valgrind flags.
49-
VALGRIND_FLAGS="--leak-check=full --track-origins=yes \
88+
VALGRIND_FLAGS="${VALGRIND_FLAGS} --leak-check=full --track-origins=yes \
5089
--trace-children=yes --show-leak-kinds=definite,indirect,possible \
5190
--errors-for-leak-kinds=definite,indirect,possible"
5291
# There are some more flags that can be reasonable to use, e.g., for debugging reasons if you found an error.
@@ -55,18 +94,8 @@ VALGRIND_FLAGS="--leak-check=full --track-origins=yes \
5594
# For more detailed outputs: -read-var-info=yes --read-inline-info=yes --gen-suppressions=all
5695
# Warning: --show-leak-kinds=all will find a lot of still reachable leaks. This is not necessarily a problem.
5796

58-
# Check if a second argument is provided. If yes, add the flag to incorporate the Valgrind suppression file.
59-
if ! [ ${2-x} = x ]; then
60-
if [ -f "$2" ]; then
61-
VALGRIND_FLAGS="${VALGRIND_FLAGS} --suppressions=${2}"
62-
else
63-
echo "ERROR: If a second argument is provided, this must be a valid valgrind suppression file."
64-
exit 1
65-
fi
66-
fi
67-
6897
# Run valgrind on given file with flags and write output to OUTPUT_FILE.
69-
valgrind $VALGRIND_FLAGS "${FILE}" > /dev/null 2>"${OUTPUT_FILE}"
98+
mpirun -n $num_procs valgrind $VALGRIND_FLAGS "${FILE}" > /dev/null 2>"${OUTPUT_FILE}"
7099

71100
# Parse valgrind output.
72101
declare -a VALGRIND_RULES=(
@@ -82,6 +111,7 @@ declare -a VALGRIND_RULES=(
82111
"^==.*== Argument .* of function .* has a fishy (possibly negative) value: .*$"
83112
"^==.*== .*alloc() with size 0$"
84113
"^==.*== Invalid alignment value: .* (should be power of 2)$"
114+
"^==.*== Conditional jump or move depends on uninitialised value(s)"
85115
)
86116
report_id=1
87117
status=0
@@ -122,5 +152,8 @@ while IFS= read -r line; do
122152
fi
123153
done < "${OUTPUT_FILE}"
124154

125-
rm -f "${OUTPUT_FILE}"
155+
# Remove the output file only if the checks were error free.
156+
if [ "$status" -eq 0 ]; then
157+
rm -f "${OUTPUT_FILE}"
158+
fi
126159
exit "${status}"

0 commit comments

Comments
 (0)