mirror of
https://github.com/PCRE2Project/pcre2.git
synced 2025-10-16 22:35:45 +08:00

An additional testing argument, `-malloc` is added to pcre2test and to RunTest. The ManyConfig tests run this now in CI. We exercise each malloc failure in the core code by counting how many mallocs are done, then repeating compilation and matching with a failure on each successive malloc.
544 lines
16 KiB
Bash
Executable File
544 lines
16 KiB
Bash
Executable File
#! /bin/sh
|
|
|
|
# This is a script for the use of PCRE2 maintainers. It configures and builds
|
|
# PCRE2 with a variety of configuration options, and in each case runs the
|
|
# tests to ensure that all goes well. Every possible combination would take far
|
|
# too long, so we use a representative sample. This script should be run in the
|
|
# PCRE2 source directory.
|
|
|
|
# While debugging, it is sometimes useful to be able to cut out some of the
|
|
# tests, in order to run those that are giving errors. The following options
|
|
# do this:
|
|
#
|
|
# -noasan skip the test that uses -fsanitize=address
|
|
# -nousan skip the test that uses -fsanitize=undefined
|
|
# -nodebug skip the test that uses --enable-debug
|
|
# -nojit skip all JIT tests
|
|
# -nojitmain skip non-valgrind JIT tests
|
|
# -nojitvalgrind skip JIT tests with valgrind
|
|
# -nomain skip all the main (non-JIT) set of tests
|
|
# -nomainvalgrind skip the main (non-JIT) valgrind tests
|
|
# -notmp skip the tests in a temporary directory
|
|
# -notmpjit skip the JIT test in a temporary directory
|
|
# -noebcdic skip the EBCDIC tests
|
|
# -novalgrind skip all the valgrind tests
|
|
|
|
# Alternatively, if any of those names are given with '+' instead of '-no',
|
|
# only those groups named with '+' are run (e.g. +jit). If -dummy is given,
|
|
# no tests are actually run - this provides a means of testing the selectors.
|
|
|
|
# The -v option causes a call to 'pcre2test -C' to happen for each
|
|
# configuration.
|
|
|
|
useasan=1
|
|
useusan=1
|
|
usedebug=1
|
|
usejit=1
|
|
usejitvalgrind=1
|
|
usemain=1
|
|
usemainvalgrind=1
|
|
usetmp=1
|
|
usetmpjit=1
|
|
useebcdic=1
|
|
usebcdicjit=1
|
|
usevalgrind=1
|
|
|
|
dummy=0
|
|
seenplus=0
|
|
verbose=0
|
|
|
|
while [ $# -gt 0 ] ; do
|
|
case $1 in
|
|
+*) if [ $seenplus -eq 0 ]; then
|
|
useasan=0
|
|
useusan=0
|
|
usedebug=0
|
|
usejit=0
|
|
usejitvalgrind=0
|
|
usemain=0
|
|
usemainvalgrind=0
|
|
usetmp=0
|
|
usetmpjit=0
|
|
useebcdic=0
|
|
useebcdicjit=0
|
|
usevalgrind=0
|
|
seenplus=1
|
|
fi;;
|
|
esac
|
|
|
|
case $1 in
|
|
-dummy) dummy=1;;
|
|
-v) verbose=1;;
|
|
-noasan) useasan=0;;
|
|
-nousan) useusan=0;;
|
|
-nodebug) usedebug=0;;
|
|
-nojit) usejit=0; usejitvalgrind=0; usetmpjit=0; useebcdicjit=0;;
|
|
-nojitmain) usejit=0;;
|
|
-nojitvalgrind) usejitvalgrind=0;;
|
|
-nomain) usemain=0; usemainvalgrind=0;;
|
|
-nomainvalgrind) usemainvalgrind=0;;
|
|
-notmp) usetmp=0; usetmpjit=0;;
|
|
-notmpjit) usetmpjit=0;;
|
|
-noebcdic) useebcdic=0; useebcdicjit=0;;
|
|
-noebcdicjit) useebcdicjit=0;;
|
|
-novalgrind) usevalgrind=0;;
|
|
+asan) useasan=1;;
|
|
+usan) useusan=1;;
|
|
+debug) usedebug=1;;
|
|
+jit) usejit=1; usejitvalgrind=1; usetmpjit=1; useebcdicjit=1;;
|
|
+jitmain) usejit=1;;
|
|
+jitvalgrind) usejitvalgrind=1;;
|
|
+main) usemain=1; usemainvalgrind=1;;
|
|
+mainvalgrind) usemainvalgrind=1;;
|
|
+tmp) usetmp=1;;
|
|
+tmpjit) usetmpjit=1;;
|
|
+ebcdic) useebcdic=1;;
|
|
+ebcdicjit) useebcdicjit=1;;
|
|
+valgrind) usevalgrind=1; usejitvalgrind=1; usemainvalgrind=1;;
|
|
*) echo "Unknown option '$1'"; exit 1;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ $usejitvalgrind -eq 0 -a $usemainvalgrind -eq 0 ] ; then
|
|
usevalgrind=0
|
|
fi
|
|
|
|
# This is in case the caller has set aliases (as I do - PH)
|
|
|
|
unset cp ls mv rm
|
|
|
|
# This is a temporary directory for testing out-of-line builds
|
|
|
|
tmp=/tmp/pcre2testing
|
|
|
|
# Don't bother with compiler optimization for most tests; it just slows down
|
|
# compilation a lot (and running the tests themselves is quick). However, one
|
|
# special test turns optimization on, because it can provoke some compiler
|
|
# warnings.
|
|
|
|
CFLAGS="-g"
|
|
OFLAGS="-O0"
|
|
CC="${CC:=cc}"
|
|
ISGCC=0
|
|
|
|
# If the compiler is GCC, add a lot of warning switches.
|
|
|
|
CC_VER_OUTPUT=`printf '#if defined(__GNUC__) && !defined(__clang__)\nGCC=yes\n#endif\n' | $CC -E -`
|
|
if [ $? -eq 0 ] && (echo "$CC_VER_OUTPUT" | grep GCC=yes) >/dev/null; then
|
|
echo "Treating $CC as GCC"
|
|
ISGCC=1
|
|
CFLAGS="$CFLAGS -Wall"
|
|
CFLAGS="$CFLAGS -Wextra"
|
|
CFLAGS="$CFLAGS -Wno-overlength-strings"
|
|
CFLAGS="$CFLAGS -Wpointer-arith"
|
|
CFLAGS="$CFLAGS -Wwrite-strings"
|
|
CFLAGS="$CFLAGS -Wundef"
|
|
CFLAGS="$CFLAGS -Wshadow"
|
|
CFLAGS="$CFLAGS -Wmissing-field-initializers"
|
|
CFLAGS="$CFLAGS -Wunused-parameter"
|
|
CFLAGS="$CFLAGS -Wformat"
|
|
CFLAGS="$CFLAGS -Wbad-function-cast"
|
|
CFLAGS="$CFLAGS -Wmissing-declarations"
|
|
CFLAGS="$CFLAGS -Wnested-externs"
|
|
CFLAGS="$CFLAGS -pedantic"
|
|
CFLAGS="$CFLAGS -Wuninitialized"
|
|
CFLAGS="$CFLAGS -Wmaybe-uninitialized"
|
|
CFLAGS="$CFLAGS -Wmissing-prototypes"
|
|
CFLAGS="$CFLAGS -Wstrict-prototypes"
|
|
CFLAGS="$CFLAGS -Warray-bounds"
|
|
CFLAGS="$CFLAGS -Wformat-overflow=2"
|
|
CFLAGS="$CFLAGS -Wformat-truncation=1"
|
|
CFLAGS="$CFLAGS -Wdeclaration-after-statement"
|
|
fi
|
|
|
|
# This function runs a single test with the set of configuration options that
|
|
# are in $opts. The source directory must be set in srcdir. The function must
|
|
# be defined as "runtest()" not "function runtest()" in order to run on
|
|
# Solaris.
|
|
|
|
runtest()
|
|
{
|
|
rm -f $srcdir/pcre2test $srcdir/pcre2grep $srcdir/pcre2_jit_test $srcdir/pcre2posix_test
|
|
testcount=`expr $testcount + 1`
|
|
|
|
if [ "$opts" = "" ] ; then
|
|
echo "[$testcount/$testtotal] Configuring with: default settings"
|
|
else
|
|
echo "[$testcount/$testtotal] Configuring with:"
|
|
echo " $opts"
|
|
fi
|
|
|
|
if [ $dummy -eq 1 ]; then return; fi
|
|
|
|
CC="$CC" CFLAGS="$CFLAGS" \
|
|
$srcdir/configure $opts >/dev/null 2>teststderrM
|
|
if [ $? -ne 0 ]; then
|
|
echo " "
|
|
echo "******** Error while configuring ********"
|
|
cat teststderrM
|
|
exit 1
|
|
fi
|
|
|
|
# There is an infelicity in the Autotools world (as of October 2015) which
|
|
# causes the message
|
|
#
|
|
# ar: `u' modifier ignored since `D' is the default (see `U')
|
|
#
|
|
# to be output while linking. This triggers an unwanted error report from this
|
|
# script, because it expects no stderr output while making. To get round this
|
|
# we filter the stderr output through sed, removing all occurrences of the
|
|
# above lines. Just for paranoia, check that sed is available before doing
|
|
# this.
|
|
|
|
echo "Making"
|
|
make -j >/dev/null 2>teststderrM
|
|
makeRC=$?
|
|
if command -v sed >/dev/null 2>&1 ; then
|
|
sed "/\`u' modifier ignored since \`D' is the default/ d" \
|
|
teststderrM > teststderrMM
|
|
mv -f teststderrMM teststderrM
|
|
fi
|
|
if [ $makeRC -ne 0 -o -s teststderrM ]; then
|
|
echo " "
|
|
echo "******** Errors or warnings while making ********"
|
|
echo " "
|
|
cat teststderrM
|
|
exit 1
|
|
fi
|
|
|
|
if [ $verbose -eq 1 ]; then
|
|
./pcre2test -C
|
|
fi
|
|
|
|
./pcre2test -C jit >/dev/null
|
|
jit=$?
|
|
./pcre2test -C pcre2-8 >/dev/null
|
|
pcre2_8=$?
|
|
|
|
echo "Running PCRE2 library tests $withvalgrind $withmalloc"
|
|
$srcdir/RunTest $valgrind $malloc >teststdoutM 2>teststderrM
|
|
|
|
if [ $? -ne 0 -o -s teststderrM ]; then
|
|
echo " "
|
|
echo "**** Test failed ****"
|
|
if [ -s teststderrM ] ; then
|
|
cat teststderrM
|
|
else
|
|
cat teststdoutM
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
if [ $pcre2_8 -eq 0 ]; then
|
|
echo "Skipping pcre2grep and pcre2posix tests: 8-bit library not compiled"
|
|
elif [ "x$withebcdic" != x ]; then
|
|
echo "Skipping pcre2grep and pcre2posix tests: tests not supported on EBCDIC"
|
|
else
|
|
echo "Running pcre2grep tests $withvalgrind"
|
|
$srcdir/RunGrepTest $valgrind >teststdoutM 2>teststderrM
|
|
if [ $? -ne 0 -o -s teststderrM ]; then
|
|
echo " "
|
|
echo "**** Test failed ****"
|
|
cat teststderrM
|
|
cat teststdoutM
|
|
exit 1
|
|
fi
|
|
echo "Running pcre2posix test $withvalgrind"
|
|
$valgrind ./pcre2posix_test >teststdoutM 2>teststderrM
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo " "
|
|
echo "**** Test failed ****"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "$jit" -eq 0 ]; then
|
|
echo "Skipping JIT regression tests: JIT is not enabled"
|
|
elif [ "x$withebcdic" != x ]; then
|
|
echo "Skipping JIT regression tests: tests not supported on EBCDIC"
|
|
else
|
|
echo "Running JIT regression tests $withvalgrind"
|
|
$jrvalgrind ./pcre2_jit_test >teststdoutM 2>teststderrM
|
|
if [ $? -ne 0 -o -s teststderrM ]; then
|
|
echo " "
|
|
echo "**** Test failed ****"
|
|
cat teststderrM
|
|
cat teststdoutM
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Update the total count whenever a new test is added; it is used to show
|
|
# progess as each test is run.
|
|
|
|
testtotal=`expr 17 \* $usemain + \
|
|
1 \* $usemain \* $usedebug + \
|
|
1 \* $usetmp + 1 \* $usetmpjit + \
|
|
1 \* $ISGCC \* $usemain + \
|
|
1 \* $ISGCC \* $usemain \* $useasan + \
|
|
1 \* $ISGCC \* $usemain \* $useusan + \
|
|
13 \* $usejit + \
|
|
2 \* $useebcdic + \
|
|
1 \* $useebcdicjit + \
|
|
2 \* $usemainvalgrind + \
|
|
2 \* $usejitvalgrind`
|
|
|
|
testcount=0
|
|
|
|
if [ $testtotal -eq 0 ] ; then
|
|
echo "** No tests selected"
|
|
exit 1
|
|
fi
|
|
|
|
valgrind=
|
|
jrvalgrind=
|
|
withvalgrind=
|
|
malloc=
|
|
withmalloc=
|
|
srcdir=.
|
|
export srcdir
|
|
|
|
if [ $usejit -ne 0 ]; then
|
|
enable_jit=--enable-jit
|
|
else
|
|
enable_jit=
|
|
fi
|
|
|
|
# If gcc is in use, run a maximally configured test with -O2, because that can
|
|
# throw up warnings that are not detected with -O0. Then run a second test with
|
|
# -fsanitize=address, which also may throw up new warnings as well as checking
|
|
# things at runtime. Finally, run another test using -fsanitize=undefined
|
|
# -std-gnu99 to check for runtime actions that are not well defined.
|
|
|
|
if [ $ISGCC -ne 0 -a $usemain -ne 0 ]; then
|
|
echo "---------- Maximally configured test with -O2 ----------"
|
|
SAVECFLAGS="$CFLAGS"
|
|
CFLAGS="-O2 $CFLAGS"
|
|
echo "CFLAGS=$CFLAGS"
|
|
opts="--disable-shared $enable_jit --enable-pcre2-16 --enable-pcre2-32"
|
|
runtest
|
|
if [ $useasan -ne 0 ]; then
|
|
echo "---------- Maximally configured test with -fsanitize=address ----------"
|
|
# Following a kernel change, sanitize address doesn't work unless the extra
|
|
# PIE options are also set.
|
|
CFLAGS="$OFLAGS $SAVECFLAGS -no-pie -fno-PIE -fsanitize=address"
|
|
echo "CFLAGS=$CFLAGS"
|
|
opts="--disable-shared $enable_jit --enable-pcre2-16 --enable-pcre2-32"
|
|
runtest
|
|
fi
|
|
# This also seems to be the case for sanitize undefined.
|
|
if [ $useusan -ne 0 ]; then
|
|
echo "------- Maximally configured test with -fsanitize=undefined -fno-sanitize=alignment -std=gnu99 -------"
|
|
CFLAGS="$OFLAGS $SAVECFLAGS -no-pie -fno-PIE -fsanitize=undefined -fno-sanitize=alignment -std=gnu99"
|
|
echo "CFLAGS=$CFLAGS"
|
|
opts="--disable-shared $enable_jit --enable-pcre2-16 --enable-pcre2-32"
|
|
runtest
|
|
fi
|
|
CFLAGS="$SAVECFLAGS"
|
|
fi
|
|
|
|
# This set of tests builds PCRE2 and runs the tests with a variety of configure
|
|
# options, in the current (source) directory. The empty configuration builds
|
|
# with all the default settings. As well as testing that these options work, we
|
|
# use --disable-shared or --disable-static except for the default test (which
|
|
# builds both) to save a bit of time by building only one version of the
|
|
# library for the subsequent tests.
|
|
|
|
echo "---------- CFLAGS for the remaining tests ----------"
|
|
CFLAGS="$OFLAGS $CFLAGS"
|
|
echo "CFLAGS=$CFLAGS"
|
|
|
|
if [ $usemain -ne 0 ]; then
|
|
if [ $usedebug -ne 0 ]; then
|
|
echo "---------- Maximally configured test with --enable-debug ----------"
|
|
opts="--disable-shared $enable_jit --enable-pcre2-16 --enable-pcre2-32 --enable-debug"
|
|
runtest
|
|
fi
|
|
|
|
echo "---------- Non-JIT tests in the current directory ----------"
|
|
for opts in \
|
|
"" \
|
|
"--disable-static" \
|
|
"--disable-shared" \
|
|
"--disable-unicode --disable-shared --enable-never-backslash-C" \
|
|
"--with-link-size=3 --disable-shared --disable-pcre2grep-callout" \
|
|
"--disable-unicode --enable-rebuild-chartables --disable-shared" \
|
|
"--disable-unicode --enable-newline-is-any --disable-shared" \
|
|
"--disable-unicode --enable-newline-is-cr --disable-shared" \
|
|
"--disable-unicode --enable-newline-is-crlf --disable-shared" \
|
|
"--disable-unicode --enable-newline-is-anycrlf --enable-bsr-anycrlf --disable-shared" \
|
|
"--enable-newline-is-any --disable-static" \
|
|
"--disable-unicode --enable-pcre2-16 --enable-debug" \
|
|
"--enable-pcre2-16 --disable-shared" \
|
|
"--disable-unicode --enable-pcre2-32" \
|
|
"--enable-pcre2-32 --disable-shared" \
|
|
"--disable-unicode --enable-pcre2-32 --enable-pcre2-16 --disable-shared" \
|
|
"--disable-unicode --enable-pcre2-32 --enable-pcre2-16 --disable-pcre2-8 --disable-shared"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
|
|
# Now run the JIT tests unless disabled
|
|
|
|
if [ $usejit -ne 0 ]; then
|
|
echo "---------- JIT tests in the current directory ----------"
|
|
for opts in \
|
|
"--disable-unicode --enable-jit --disable-shared" \
|
|
"--enable-jit --disable-shared" \
|
|
"--enable-jit --with-link-size=3 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-16 --disable-shared" \
|
|
"--disable-unicode --enable-jit --enable-pcre2-16 --disable-pcre2-8 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-16 --disable-pcre2-8 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-16 --with-link-size=3 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-16 --with-link-size=4 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-32 --disable-shared" \
|
|
"--disable-unicode --enable-jit --enable-pcre2-32 --disable-pcre2-8 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-32 --disable-pcre2-8 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-32 --with-link-size=4 --disable-shared" \
|
|
"--enable-jit --enable-pcre2-32 --enable-pcre2-16 --disable-pcre2-8 --enable-newline-is-anycrlf --enable-bsr-anycrlf --disable-shared"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
|
|
# Now run some tests with EBCDIC enabled
|
|
|
|
if [ $useebcdic -ne 0 -o $useebcdicjit -ne 0 ]; then
|
|
echo "---------- EBCDIC tests in the current directory ----------"
|
|
withebcdic="with EBCDIC"
|
|
|
|
if [ $useebcdic -ne 0 ]; then
|
|
for opts in \
|
|
"--disable-unicode --enable-ebcdic --enable-ebcdic-ignoring-compiler" \
|
|
"--disable-unicode --enable-ebcdic --enable-ebcdic-ignoring-compiler --enable-ebcdic-nl25"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
|
|
if [ $useebcdicjit -ne 0 ]; then
|
|
for opts in \
|
|
"--disable-unicode --enable-jit --enable-ebcdic --enable-ebcdic-ignoring-compiler"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
fi
|
|
|
|
withebcdic=
|
|
|
|
# Now re-run some of the tests under valgrind.
|
|
|
|
if [ $usevalgrind -ne 0 ]; then
|
|
echo "---------- Tests in the current directory using valgrind ----------"
|
|
valgrind=valgrind
|
|
withvalgrind="with valgrind"
|
|
|
|
malloc=-malloc
|
|
withmalloc="with -malloc"
|
|
|
|
if [ $usemainvalgrind -ne 0 ]; then
|
|
for opts in \
|
|
"--disable-shared" \
|
|
"--with-link-size=3 --enable-pcre2-16 --enable-pcre2-32 --disable-shared"
|
|
do
|
|
opts="--enable-valgrind $opts"
|
|
runtest
|
|
|
|
# Only need to run the first test with -malloc.
|
|
malloc=
|
|
withmalloc=
|
|
done
|
|
fi
|
|
|
|
malloc=-malloc
|
|
withmalloc="with -malloc"
|
|
|
|
if [ $usejitvalgrind -ne 0 ]; then
|
|
jrvalgrind="valgrind --tool=memcheck -q --smc-check=all-non-file --suppressions=$srcdir/testdata/valgrind-jit.supp"
|
|
for opts in \
|
|
"--enable-jit --disable-shared" \
|
|
"--enable-jit --enable-pcre2-16 --enable-pcre2-32"
|
|
do
|
|
opts="--enable-valgrind $opts"
|
|
runtest
|
|
|
|
# Only need to run the first test with -malloc.
|
|
malloc=
|
|
withmalloc=
|
|
done
|
|
fi
|
|
fi
|
|
|
|
valgrind=
|
|
jrvalgrind=
|
|
withvalgrind=
|
|
malloc=
|
|
withmalloc=
|
|
|
|
# Clean up the distribution and then do at least one build and test in a
|
|
# directory other than the source directory. It doesn't work unless the
|
|
# source directory is cleaned up first.
|
|
|
|
if [ -f Makefile ]; then
|
|
echo "Running 'make distclean'"
|
|
make distclean >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "** 'make distclean' failed"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "---------- End of tests in the source directory ----------"
|
|
echo "Removing teststdoutM and teststderrM"
|
|
rm -rf teststdoutM teststderrM
|
|
|
|
if [ $usetmp -ne 0 -o $usetmpjit -ne 0 ]; then
|
|
srcdir=`pwd`
|
|
export srcdir
|
|
|
|
if [ ! -e $tmp ]; then
|
|
mkdir $tmp
|
|
fi
|
|
|
|
if [ ! -d $tmp ]; then
|
|
echo "** Failed to create $tmp or it is not a directory"
|
|
exit 1
|
|
fi
|
|
|
|
cd $tmp
|
|
if [ $? -ne 0 ]; then
|
|
echo "** Failed to cd to $tmp"
|
|
exit 1
|
|
fi
|
|
|
|
if [ $usetmp -ne 0 ]; then
|
|
echo "---------- Tests in the $tmp directory ----------"
|
|
for opts in \
|
|
"--disable-shared"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
|
|
if [ $usetmpjit -ne 0 ]; then
|
|
echo "---------- JIT tests in the $tmp directory ----------"
|
|
for opts in \
|
|
"--enable-jit --disable-shared"
|
|
do
|
|
runtest
|
|
done
|
|
fi
|
|
|
|
echo "Removing $tmp"
|
|
rm -rf $tmp
|
|
fi
|
|
|
|
echo "---------- All done ----------"
|
|
|
|
# End
|