libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Atomic creation of fast-install relinked binary


From: Paolo Bonzini
Subject: [PATCH] Atomic creation of fast-install relinked binary
Date: Thu, 31 Jul 2008 14:39:10 +0200
User-agent: Thunderbird 2.0.0.16 (Macintosh/20080707)

This patch fixes PR35752 in GCC.

The problem is a race condition in the fast-install wrapper. The program could be called twice in a parallel make, with the second invocation starting before the first invocation of the wrapper script has finished relinking the executable. In this case, the second execution will fail.

If you are not convinced, an example is given by the following makefile (which will most likely be mangled by the mail).

----
MAKEFILE := $(lastword $(MAKEFILE_LIST))
eight_times = $(1) && $(1) && $(1) && $(1) && $(1) && $(1) && $(1) && $(1)

.PHONY: test a b try try8 try64 try512

test:;      rm -f foo; $(MAKE) -f $(MAKEFILE) try512
foo bar:;   echo false > $@; echo : >> $@
a:;         echo false > foo; echo : >> foo
b:;         . ./foo ; test $$? = 0 && echo GOOD
try: foo;   $(MAKE) -f $(MAKEFILE) -j2 a b

try8:;      @$(call eight_times, $(MAKE) -f $(MAKEFILE) try)
try64:;     @$(call eight_times, $(MAKE) -f $(MAKEFILE) try8)
try512:;    @$(call eight_times, $(MAKE) -f $(MAKEFILE) try64)
----

Most of the time, the makefile will fail after just one or two iterations. Note that target "try" does have a dependency on "foo" (akin to the dependency between the compiler and the target that executes it), but it does not matter because target "a" (the equivalent of libtool) rewrites the file under the hood.

The patch fixes the problem by relinking to a temporary file and moving the result to the correct name afterwards. This is equivalent to changing "a" as follows:

a:;         $(MAKE) -f $(MAKEFILE) bar && mv bar foo

Tested (together with the sh.test patch) on i686-pc-linux-gnu and powerpc-apple-darwin8.11.0, with the following results:

i686-pc-linux-gnu:
====================
All 124 tests passed
====================
71 tests behaved as expected.
2 tests were skipped (23 and 73).

powerpc-apple-darwin:
====================
All 106 tests passed
====================
66 tests behaved as expected.
7 tests were skipped (21, 22, 23, 25, 35, 62, 73)

Ok?

Paolo
2008-07-31  Paolo Bonzini  <address@hidden>

        * libltdl/config/ltmain.m4sh: Set up the wrapper script's
        relink_command so that it creates .libs/lt-NAME atomically.

diff --git a/libltdl/config/ltmain.m4sh b/libltdl/config/ltmain.m4sh
index b6fb29b..a5fd949 100644
--- a/libltdl/config/ltmain.m4sh
+++ b/libltdl/config/ltmain.m4sh
@@ -7301,7 +7300,13 @@ EOF
        if test "$fast_install" != no; then
          link_command="$finalize_var$compile_command$finalize_rpath"
          if test "$fast_install" = yes; then
-           relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" 
| $Xsed -e 'address@hidden@%\$progdir/\$file%g'`
+           # Make sure that the old file is replaced atomically.  While
+           # the creation of the initial executable (by the compiler/linker)
+           # need not be atomic because Makefile rules enforce dependencies,
+           # relinking happens under the hood, so we do not have this luxury.
+           relink_command=`$ECHO "X{ 
$compile_var$compile_command$compile_rpath ; } && mv @OUTPUT@ @FINAL_OUTPUT@" | 
$Xsed \
+                       -e 'address@hidden@%\$progdir/lt-\$file.\$\$%g' \
+                       -e 'address@hidden@%\$progdir/\$file%g'`
          else
            # fast_install is set to needless
            relink_command=

reply via email to

[Prev in Thread] Current Thread [Next in Thread]