+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
$(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
+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
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)
"RUNTEST=$(RUNTEST)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)"
-all:
+all: $(EXTRA_RULES)
@echo "Nothing to be done for all..."
.NOEXPORT:
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 = \
-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 \
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
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
***********************
ac_subst_vars='LTLIBOBJS
LIBOBJS
+EXTRA_RULES
EGREP
GREP
CPP
+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
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 \
--- /dev/null
+/* 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);
+}