This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/3] Isolate test case execution from external environment


Hi,

Currently the testsuite only works correctly for prefixes that have a
valid sysroot and uses the ld.so.cache in the sysroot to pick up
dependencies for test cases. Ideally test case execution should be
controlled and should not be affected by the prefix the result is going
to be installed to.

This patch does two things: first, use --inhibit-ldcache to prevent
ld.so from using any ld.so.cache in the test cases and second, create
symlinks for external dependencies within the build environment so that
the test case executions don't need any search paths outside the build
directory.

There are two dinstinct changes in this:
1) libgcc_s.so.1 is dynmically loaded by pthreads and hence it cannot
be detected as a dependency. It would have to be found and symlinked
into the build directory before test cases are executed
2) Dependencies of running test case binaries as well as shared
libraries that they may link to.

I have tested the patch with a make check on x86 shared build. Fully
static build is broken in glibc due to which I could not test it, see bz
13679.

Regards,
Siddhesh


ChangeLog:

2012-04-06  Siddhesh Poyarekar  <siddhesh@redhat.com>

	* Makeconfig (run-program-prefix): Use --inhibit-ldcache.
	(list-deps-cmd): Define.
	(rtld-verify-binary): Define.
	* Makerules: Call $(symlink-deps) for built modules. Remove
	the tests/lib directory on cleanup.
	* Rules (tests-init): New target. Perform tasks before
	executing test cases.
	(libgcc-symlinked): New target. Link in libgcc_s.so.1 into
	build directory. Use rtld-verify-binary.
	(symlink-deps): Define. Use list-deps-cmd.
	* posix/tst-exec.c (do_test): Adjust for --inhibit-ldcache.
	* posix/tst-spawn.c (do_test): Adjust for --inhibit-ldcache.
---
 Makeconfig        |   32 +++++++++++++++++++++++++++++++-
 Makerules         |    2 ++
 Rules             |   47 ++++++++++++++++++++++++++++++++++++++++++++++-
 posix/tst-exec.c  |    7 ++++---
 posix/tst-spawn.c |   24 +++++++++++++-----------
 5 files changed, 96 insertions(+), 16 deletions(-)

diff --git a/Makeconfig b/Makeconfig
index 7a46d44..126599a 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -565,12 +565,42 @@ sysdep-library-path = \
 $(subst $(empty) ,:,$(strip $(patsubst -Wl$(comma)-rpath-link=%, %,\
 				       $(filter -Wl$(comma)-rpath-link=%,\
 						$(sysdep-LDFLAGS)))))
+
+program-library-path = \
+$(strip $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)):$(objdir)/tests/lib)
+
 run-program-prefix = $(if $(filter $(notdir $(built-program-file)),\
 				   $(tests-static) $(xtests-static)),, \
 			  $(elf-objpfx)$(rtld-installed-name) \
-			  --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)))
+			  --inhibit-ldcache \
+			  --library-path $(program-library-path))
+
+# GCC can give us the search paths it uses to find libraries during linking.
+# For other compilers (or to override this), use the test-lib-paths
+# variable in configparms
+
+ifndef test-lib-paths
+ifeq ($(CC),gcc)
+test-lib-paths = $(strip $(shell gcc --print-search-dirs | grep libraries | cut -d '=' -f 2))
+else
+test-lib-paths =
+endif
+endif
+
+# To get a list of dependencies of a binary, call as $(call list-deps-cmd,$(your-bin))
+ifdef test-lib-paths
+list-deps-prefix = $(run-program-prefix):$(test-lib-paths)
+else
+list-deps-prefix = $(run-program-prefix)
+endif
+list-deps-cmd = $(list-deps-prefix) --list $(1)
+
+# Verify if a binary is dynamically linked and is readable by the current linker
+rtld-verify-binary = $(elf-objpfx)$(rtld-installed-name) --verify $(1)
+
 else
 run-program-prefix =
+rtld-verify-binary =
 endif
 # Never use $(run-program-prefix) for the statically-linked %-bp test programs
 built-program-cmd = $(patsubst %,$(run-program-prefix),\
diff --git a/Makerules b/Makerules
index d184be6..4b23a5e 100644
--- a/Makerules
+++ b/Makerules
@@ -638,6 +638,7 @@ $(extra-modules-build:%=$(objpfx)%.so): $(objpfx)%.so: \
 		$(objpfx)%.os $(shlib-lds) \
 		$(common-objpfx)libc.so $(common-objpfx)libc_nonshared.a
 	$(build-module)
+	$(call symlink-deps,$@)
 endif
 
 +depfiles := $(sources:.c=.d) \
@@ -1299,6 +1300,7 @@ do-tests-clean:
 						      $(test-srcs)) \
 				     $(addsuffix -bp.out,$(tests) $(xtests) \
 							 $(test-srcs)))
+	-rm -rf $(objdir)/tests
 
 # Remove the object files.
 common-mostlyclean:
diff --git a/Rules b/Rules
index 3c61a29..96df5dc 100644
--- a/Rules
+++ b/Rules
@@ -84,6 +84,35 @@ common-generated += dummy.o dummy.c
 
 # This makes all the auxiliary and test programs.
 
+libgcc-symlinked = $(objdir)/tests/lib/$(libgcc-so-name)
+
+ifdef test-lib-paths
+libgcc-lib-paths = $(program-library-path):$(test-lib-paths)
+else
+libgcc-lib-paths = $(program-library-path)
+endif
+find-libgcc = $(strip $(foreach match, $(subst :, ,$(libgcc-lib-paths)), \
+				$(wildcard $(match)/$(libgcc-so-name))))
+
+tests-init:$(libgcc-symlinked)
+
+$(libgcc-symlinked):
+	mkdir -p $(objdir)/tests/lib
+	@for lib in $(find-libgcc); do \
+		$(call rtld-verify-binary,$$lib); \
+		if [ $$? -eq 2 ]; then \
+			ln -s $$lib $@ ; \
+			exit 0; \
+		fi; \
+	done && \
+	echo "*****************************************************"; \
+	echo "ERROR: We could not find $(libgcc-so-name) in your"   ; \
+	echo "system. If it is not in the library paths, specify a" ; \
+	echo "path to search in using the test-lib-paths variable"  ; \
+	echo "in configparms."                                      ; \
+	echo "*****************************************************"; \
+	exit 1
+
 .PHONY: others tests
 ifeq ($(build-programs),yes)
 others: $(addprefix $(objpfx),$(others) $(sysdep-others) $(extra-objs))
@@ -98,7 +127,8 @@ ifeq ($(build-bounded),yes)
 tests-bp.out = $(tests:%=$(objpfx)%-bp.out)
 xtests-bp.out = $(xtests:%=$(objpfx)%-bp.out)
 endif
-tests: $(tests:%=$(objpfx)%.out) $(tests-bp.out)
+.SECONDEXPANSION:
+tests: tests-init $(tests:%=$(objpfx)%.out) $(tests-bp.out)
 xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-bp.out)
 endif
 
@@ -152,13 +182,28 @@ ifneq "$(strip $(tests) $(xtests) $(test-srcs))" ""
 # These are the implicit rules for making test outputs
 # from the test programs and whatever input files are present.
 
+ifeq (yes,$(build-shared))
+symlink-deps = mkdir -p $(objdir)/tests/lib && \
+		$(call list-deps-cmd, $(1)) | \
+		grep -v "$(objdir)" | \
+		grep " => " | \
+		sed 's/\t[^ ]\+ => \([^ ]*\) ([x0-9a-f]\+)/\1 /g' | \
+		while read dep; do \
+			ln -s $$dep $(objdir)/tests/lib/ ; \
+		done
+else
+symlink-deps =
+endif
+
 make-test-out = GCONV_PATH=$(common-objpfx)iconvdata LC_ALL=C \
 		$($*-ENV) $(built-program-cmd) $($*-ARGS)
 $(objpfx)%-bp.out: %.input $(objpfx)%-bp
 	$(make-test-out) > $@ < $(word 1,$^)
 $(objpfx)%.out: %.input $(objpfx)%
+	$(call symlink-deps,$(built-program-file))
 	$(make-test-out) > $@ < $(word 1,$^)
 $(objpfx)%.out: /dev/null $(objpfx)%	# Make it 2nd arg for canned sequence.
+	$(call symlink-deps,$(built-program-file))
 	$(make-test-out) > $@
 
 endif	# tests
diff --git a/posix/tst-exec.c b/posix/tst-exec.c
index 8e88ab8..0e7a78c 100644
--- a/posix/tst-exec.c
+++ b/posix/tst-exec.c
@@ -126,8 +126,9 @@ do_test (int argc, char *argv[])
   int status;
 
   /* We must have
-     - four parameters left of called initially
+     - five parameters left of called initially
        + path for ld.so
+       + "--inhibit-ldcache"
        + "--library-path"
        + the library path
        + the application name
@@ -145,7 +146,7 @@ do_test (int argc, char *argv[])
       return handle_restart (argv[1], argv[2], argv[3]);
     }
 
-  if (argc != 5)
+  if (argc != 6)
     error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);
 
   /* Prepare the test.  We are creating two files: one which file descriptor
@@ -185,7 +186,7 @@ do_test (int argc, char *argv[])
       snprintf (fd2name, sizeof fd2name, "%d", fd2);
 
       /* This is the child.  Construct the command line.  */
-      execl (argv[1], argv[1], argv[2], argv[3], argv[4], "--direct",
+      execl (argv[1], argv[1], argv[2], argv[3], argv[4], argv[5], "--direct",
 	     "--restart", fd1name, fd2name, name1, NULL);
 
       error (EXIT_FAILURE, errno, "cannot exec");
diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c
index 162fd72..466cc56 100644
--- a/posix/tst-spawn.c
+++ b/posix/tst-spawn.c
@@ -168,11 +168,12 @@ do_test (int argc, char *argv[])
   char fd2name[18];
   char fd3name[18];
   char fd4name[18];
-  char *spargv[12];
+  char *spargv[13];
 
   /* We must have
-     - four parameters left of called initially
+     - five parameters left of called initially
        + path for ld.so
+       + "--inhibit-ldcache"
        + "--library-path"
        + the library path
        + the application name
@@ -183,7 +184,7 @@ do_test (int argc, char *argv[])
        + thhe duped second descriptor
        + the name of the closed descriptor
   */
-  if (argc != (restart ? 6 : 5))
+  if (argc != 6)
     error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc);
 
   if (restart)
@@ -239,14 +240,15 @@ do_test (int argc, char *argv[])
    spargv[1] = argv[2];
    spargv[2] = argv[3];
    spargv[3] = argv[4];
-   spargv[4] = (char *) "--direct";
-   spargv[5] = (char *) "--restart";
-   spargv[6] = fd1name;
-   spargv[7] = fd2name;
-   spargv[8] = fd3name;
-   spargv[9] = fd4name;
-   spargv[10] = name1;
-   spargv[11] = NULL;
+   spargv[4] = argv[5];
+   spargv[5] = (char *) "--direct";
+   spargv[6] = (char *) "--restart";
+   spargv[7] = fd1name;
+   spargv[8] = fd2name;
+   spargv[9] = fd3name;
+   spargv[10] = fd4name;
+   spargv[11] = name1;
+   spargv[12] = NULL;
 
    if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0)
      error (EXIT_FAILURE, errno, "posix_spawn");
-- 
1.7.7.6


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]