mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-24 18:44:20 +08:00
Integrate PR 12649's race detector directly in the testsuite machinery
This integrates Jan Kratochvil's nice race reproducer from PR testsuite/12649 into the testsuite infrustructure directly. With this, one only has to do either 'make check-read1' or 'make check READ1="1"' to preload the read1.so library into expect. Currently only enabled for glibc/GNU systems, and if build==host==target. gdb/testsuite/ChangeLog: * Makefile.in (EXTRA_RULES, CC): New variables, get from configure. (EXPECT): Handle READ1 being set. (all): Depend on EXTRA_RULES. (check-read1, expect-read1, read1.so, read1): New rules. * README (Testsuite Parameters): Document the READ1 make variable. (Race detection): New section. * configure: Regenerate. * configure.ac: If build==host==target, and running under a GNU/glibc system, add read1 to the extra Makefile rules. (EXTRA_RULES): AC_SUBST it. * lib/read1.c: New file. gdb/ChangeLog: * Makefile.in (check-read1): New rule.
This commit is contained in:
parent
469a34932a
commit
2a31c6236d
@ -1,3 +1,7 @@
|
||||
2014-08-20 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* Makefile.in (check-read1): New rule.
|
||||
|
||||
2014-08-20 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* value.c (value_from_contents_and_address): Strip resolved_type's
|
||||
|
@ -1098,6 +1098,14 @@ check-perf: force
|
||||
$(MAKE) $(TARGET_FLAGS_TO_PASS) check-perf; \
|
||||
else true; fi
|
||||
|
||||
check-read1: force
|
||||
@if [ -f testsuite/Makefile ]; then \
|
||||
rootme=`pwd`; export rootme; \
|
||||
rootsrc=`cd $(srcdir); pwd`; export rootsrc; \
|
||||
cd testsuite; \
|
||||
$(MAKE) $(TARGET_FLAGS_TO_PASS) check-read1; \
|
||||
else true; fi
|
||||
|
||||
# The idea is to parallelize testing of multilibs, for example:
|
||||
# make -j3 check//sh-hms-sim/{-m1,-m2,-m3,-m3e,-m4}/{,-nofpu}
|
||||
# will run 3 concurrent sessions of check, eventually testing all 10
|
||||
|
@ -1,3 +1,19 @@
|
||||
2014-08-20 Pedro Alves <palves@redhat.com>
|
||||
Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* Makefile.in (EXTRA_RULES, CC): New variables, get from
|
||||
configure.
|
||||
(EXPECT): Handle READ1 being set.
|
||||
(all): Depend on EXTRA_RULES.
|
||||
(check-read1, expect-read1, read1.so, read1): New rules.
|
||||
* README (Testsuite Parameters): Document the READ1 make variable.
|
||||
(Race detection): New section.
|
||||
* configure: Regenerate.
|
||||
* configure.ac: If build==host==target, and running under a
|
||||
GNU/glibc system, add read1 to the extra Makefile rules.
|
||||
(EXTRA_RULES): AC_SUBST it.
|
||||
* lib/read1.c: New file.
|
||||
|
||||
2014-08-20 Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
* gdb.dwarf2/data-loc.exp: Add additional tests exercising
|
||||
|
@ -39,9 +39,17 @@ ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.btrace gdb.cell gdb.cp \
|
||||
gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml \
|
||||
$(SUBDIRS)
|
||||
|
||||
EXPECT = `if [ -f $${rootme}/../../expect/expect ] ; then \
|
||||
echo $${rootme}/../../expect/expect ; \
|
||||
else echo expect ; fi`
|
||||
EXTRA_RULES = @EXTRA_RULES@
|
||||
|
||||
CC=@CC@
|
||||
|
||||
EXPECT = `if [ "$${READ1}" != "" ] ; then \
|
||||
echo $${rootme}/expect-read1; \
|
||||
elif [ -f $${rootme}/../../expect/expect ] ; then \
|
||||
echo $${rootme}/../../expect/expect ; \
|
||||
else \
|
||||
echo expect ; \
|
||||
fi`
|
||||
|
||||
RUNTEST = $(RUNTEST_FOR_TARGET)
|
||||
|
||||
@ -84,7 +92,7 @@ TARGET_FLAGS_TO_PASS = \
|
||||
"RUNTEST=$(RUNTEST)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS)"
|
||||
|
||||
all:
|
||||
all: $(EXTRA_RULES)
|
||||
@echo "Nothing to be done for all..."
|
||||
|
||||
.NOEXPORT:
|
||||
@ -146,6 +154,9 @@ installcheck:
|
||||
check: all $(abs_builddir)/site.exp
|
||||
$(MAKE) $(CHECK_TARGET)
|
||||
|
||||
check-read1:
|
||||
$(MAKE) READ1="1" check
|
||||
|
||||
# All the hair to invoke dejagnu. A given invocation can just append
|
||||
# $(RUNTESTFLAGS)
|
||||
DO_RUNTEST = \
|
||||
@ -230,6 +241,7 @@ clean mostlyclean:
|
||||
-rm -f core.* *.tf *.cl *.py tracecommandsscript copy1.txt zzz-gdbscript
|
||||
-rm -f *.dwo *.dwp
|
||||
-rm -rf outputs temp cache
|
||||
-rm -f read1.so expect-read1
|
||||
if [ x"${ALL_SUBDIRS}" != x ] ; then \
|
||||
for dir in ${ALL_SUBDIRS}; \
|
||||
do \
|
||||
@ -263,3 +275,27 @@ config.status: configure
|
||||
TAGS: force
|
||||
find $(srcdir) -name '*.exp' -print | \
|
||||
etags --regex='/proc[ \t]+\([^ \t]+\)/\1/' -
|
||||
|
||||
# Build the expect wrapper script that preloads the read1.so library.
|
||||
expect-read1:
|
||||
@echo Making expect-read1
|
||||
@rm -f expect-read1-tmp
|
||||
@touch expect-read1-tmp
|
||||
@echo "# THIS FILE IS GENERATED -*- buffer-read-only: t -*- \n" >>expect-read1-tmp
|
||||
@echo "# vi:set ro: */\n\n" >>expect-read1-tmp
|
||||
@echo "# To regenerate this file, run:\n" >>expect-read1-tmp
|
||||
@echo "# make clean; make/\n" >>expect-read1-tmp
|
||||
@echo "export LD_PRELOAD=`pwd`/read1.so" >>expect-read1-tmp
|
||||
@echo 'exec expect "$$@"' >>expect-read1-tmp
|
||||
@chmod +x expect-read1-tmp
|
||||
@mv expect-read1-tmp expect-read1
|
||||
|
||||
# Build the read1.so preload library. This overrides the `read'
|
||||
# function, making it read one byte at a time. Running the testsuite
|
||||
# with this catches racy tests.
|
||||
read1.so: lib/read1.c
|
||||
$(CC) -o $@ ${srcdir}/lib/read1.c -Wall -g -shared -fPIC $(CFLAGS)
|
||||
|
||||
# Build the read1 machinery.
|
||||
.PHONY: read1
|
||||
read1: read1.so expect-read1
|
||||
|
@ -176,6 +176,47 @@ Example:
|
||||
If not using GNU make then the value is passed directly to runtest.
|
||||
If not specified, all tests are run.
|
||||
|
||||
READ1
|
||||
|
||||
This make (not runtest) variable is used to specify whether the
|
||||
testsuite preloads the read1.so library into expect. Any non-empty
|
||||
value means true. See "Race detection" below.
|
||||
|
||||
Race detection
|
||||
**************
|
||||
|
||||
The testsuite includes a mechanism that helps detect test races.
|
||||
|
||||
For example, say the program running under expect outputs "abcd", and
|
||||
a test does something like this:
|
||||
|
||||
expect {
|
||||
"a.*c" {
|
||||
}
|
||||
"b" {
|
||||
}
|
||||
"a" {
|
||||
}
|
||||
}
|
||||
|
||||
Which case happens to match depends on what expect manages to read
|
||||
into its internal buffer in one go. If it manages to read three bytes
|
||||
or more, then the first case matches. If it manages to read two
|
||||
bytes, then the second case matches. If it manages to read only one
|
||||
byte, then the third case matches.
|
||||
|
||||
To help detect these cases, the race detection mechanism preloads a
|
||||
library into expect that forces the `read' system call to always
|
||||
return at most 1 byte.
|
||||
|
||||
To enable this, either pass a non-empty value in the READ1 make
|
||||
variable, or use the check-read1 make target instead of check.
|
||||
|
||||
Examples:
|
||||
|
||||
make -j10 check-read1 TESTS="*/paginate-*.exp"
|
||||
make -j10 check READ1="1"
|
||||
|
||||
Testsuite Configuration
|
||||
***********************
|
||||
|
||||
|
10
gdb/testsuite/configure
vendored
10
gdb/testsuite/configure
vendored
@ -591,6 +591,7 @@ ac_includes_default="\
|
||||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
EXTRA_RULES
|
||||
EGREP
|
||||
GREP
|
||||
CPP
|
||||
@ -3448,6 +3449,15 @@ done
|
||||
|
||||
|
||||
|
||||
if test "${build}" = "${host}" -a "${host}" = "${target}"; then
|
||||
case "${host}" in
|
||||
*gnu*)
|
||||
EXTRA_RULES=read1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.dlang/Makefile gdb.fortran/Makefile gdb.gdb/Makefile gdb.go/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.guile/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.perf/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
|
@ -87,6 +87,15 @@ AC_CHECK_HEADERS(pthread.h)
|
||||
|
||||
AC_EXEEXT
|
||||
|
||||
if test "${build}" = "${host}" -a "${host}" = "${target}"; then
|
||||
case "${host}" in
|
||||
*gnu*)
|
||||
EXTRA_RULES=read1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(EXTRA_RULES)
|
||||
|
||||
AC_OUTPUT([Makefile \
|
||||
gdb.ada/Makefile \
|
||||
gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.btrace/Makefile \
|
||||
|
40
gdb/testsuite/lib/read1.c
Normal file
40
gdb/testsuite/lib/read1.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* This is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2011-2014 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Wrap 'read', forcing it to return only one byte at a time, if
|
||||
reading from the terminal. */
|
||||
|
||||
ssize_t
|
||||
read (int fd, void *buf, size_t count)
|
||||
{
|
||||
static ssize_t (*read2) (int fd, void *buf, size_t count) = NULL;
|
||||
if (read2 == NULL)
|
||||
{
|
||||
unsetenv ("LD_PRELOAD");
|
||||
read2 = dlsym (RTLD_NEXT, "read");
|
||||
}
|
||||
if (count > 1 && isatty (fd) >= 1)
|
||||
count = 1;
|
||||
return read2 (fd, buf, count);
|
||||
}
|
Loading…
Reference in New Issue
Block a user