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]

Re: [PATCH 3/3] Isolate test case execution from externalenvironment


Hi,

This is the second take of the patch I had posted earlier
(http://sourceware.org/ml/libc-alpha/2012-04/msg00229.html). The aim of
this patch is to isolate the test case execution to ensure that the
test cases only pick libraries from within the test environment unless
absolutely necessary. Any external libraries needed are evaluated and
linked into a single directory within the build directory (tests/lib).
Tested on x86_64.

This patch needs the patch I had submitted earlier because it uses
LIBGCC_S_SO in the right header:

http://sourceware.org/ml/libc-alpha/2012-04/msg00911.html

Regards,
Siddhesh

ChangeLog:

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

	* Makeconfig (run-program-prefix): Use --inhibit-cache.
	(test-lib-paths): Get library search path used by compiler.
	(list-deps-cmd): Define.
	(rtld-verify-binary): Define.
	* Makerules (extra-modules-build): 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-test): Program to print the value of LIBGCC_S_SO.
	(tests-init, libgcc-done): New targets. Run libgcc-test and
	look for it in test-lib-paths. Use rtld-verify-binary.
	(tests): Depend on tests-init.
	(symlink-deps): Define. Use list-deps-cmd.
	($(objpfx)%.out): Use symlink-deps.
	* posix/tst-exec.c (do_test): Adjust for --inhibit-cache.
	* posix/tst-spawn.c (do_test): Adjust for --inhibit-cache.
---
 Makeconfig        |   28 +++++++++++++++++++++-
 Makerules         |    2 +
 Rules             |   66 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 posix/tst-exec.c  |    7 +++--
 posix/tst-spawn.c |   24 ++++++++++---------
 6 files changed, 130 insertions(+), 16 deletions(-)

diff --git a/Makeconfig b/Makeconfig
index 4364296..07c7dd8 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -563,12 +563,38 @@ 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-cache \
+			  --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
+test-lib-paths = $(strip $(shell $(CC) --print-search-dirs | grep libraries | cut -d '=' -f 2))
+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 72667db..244e3b8 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) \
@@ -1297,6 +1298,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..2fd34bd 100644
--- a/Rules
+++ b/Rules
@@ -84,6 +84,55 @@ common-generated += dummy.o dummy.c
 
 # This makes all the auxiliary and test programs.
 
+ifdef test-lib-paths
+libgcc-lib-paths = $(program-library-path):$(test-lib-paths)
+else
+libgcc-lib-paths = $(program-library-path)
+endif
+find-libgcc = $(strip $(subst :, ,$(libgcc-lib-paths)))
+
+.ONESHELL:
+$(objdir)/tests/libgcc-test.c:
+	mkdir -p $(objdir)/tests
+	cat > $@ << EOF
+	#include <gnu/lib-names.h>
+	#include <stdio.h>
+	int main() {puts(LIBGCC_S_SO);}
+	EOF
+
+$(objdir)/tests/libgcc-test:$(objdir)/tests/libgcc-test.c
+	$(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $<
+
+# I cannot use the libgcc soname link directly as a dep since we
+# don't know yet what the name would be. Even if we did, it would
+# be inside the shell and not available to the make system.
+.ONESHELL:
+$(objdir)/tests/libgcc-done:$(objdir)/tests/libgcc-test
+	@libgcc=$$($<)
+	mkdir -p $(objdir)/tests/lib
+	for libdir in $(find-libgcc); do
+		if [ -e $$libdir/$$libgcc ]; then
+			lib=$$libdir/$$libgcc
+			$(call rtld-verify-binary,$$lib)
+			if [ $$? -eq 2 ]; then
+				ln -s $$lib $(objdir)/tests/lib/
+				touch $(objdir)/tests/libgcc-done
+				exit 0
+			fi
+		fi
+	done
+	echo "*****************************************************"
+	echo "ERROR: We could not find $$libgcc 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:tests-init
+
+tests-init:$(objdir)/tests/libgcc-done
+
 .PHONY: others tests
 ifeq ($(build-programs),yes)
 others: $(addprefix $(objpfx),$(others) $(sysdep-others) $(extra-objs))
@@ -98,7 +147,7 @@ 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)
+tests: tests-init $(tests:%=$(objpfx)%.out) $(tests-bp.out)
 xtests: tests $(xtests:%=$(objpfx)%.out) $(xtests-bp.out)
 endif
 
@@ -152,13 +201,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..eae320f 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-cache"
        + "--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..c737194 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-cache"
        + "--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]