[Reproducible-builds] Link Time Optimization breaks reproducible builds

conchur at web.de conchur at web.de
Tue Feb 10 11:18:51 UTC 2015


Hi,

thanks for the detailed answer. The proposed things will definitely help
me. But I just got interested in the inner workings of the gcc lto stuff.
So I will just ask some things just out of curiosity.

First, is there already some kind of documentation about this problem in
the GCC bug tracker or in the reproducible wiki?

[...]
> For a proper solution, I believe a patch to GCC is needed. A trivial
> test case gives me this:
> 
> $ objdump -x f | grep \.o$
> 0000000000000000 l df *ABS* 0000000000000000 ccwqwTSn.ltrans0.o
> 
> The temporary object file created by GCC has a random name which gets
> included in the final binary. If GCC could use a deterministic file
> name, I believe this would solve the issue.

Ok, there are many make_temp_file in gcc/lto-wrapper.o these could be
the source for the randomness? I just replaced my
 /usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
with some simple wrapper script (lto-wrapper2 is the old version):

#! /bin/sh
echo $COLLECT_GCC >> /tmp/collect_gcc
echo "$@" >> /tmp/foobar
cp $(echo "$1"|sed 's/^.//') /tmp/input
/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper2 "$@"|tee /tmp/output

The arguments were:

@/tmp/cciTQ4Dg

The content of this file was:

-fresolution=/tmp/cc27YWea.res
_obj/GlideHQ/tc-1.1+/fxt1.o
[...]
_obj/GlideHQ/tc-1.1+/s2tc/s2tc_libtxc_dxtn.o


The output was:

/tmp/ccjdkQfg.ltrans0.ltrans.o
[...]
/tmp/ccjdkQfg.ltrans31.ltrans.o

The random filenames in the final build were:

0000000000000000 l    df *ABS*  0000000000000000              ccjdkQfg.ltrans0.o
[...]
0000000000000000 l    df *ABS*  0000000000000000              ccjdkQfg.ltrans31.o

So it looks at first glance like the lto-wrapper generates the
random string. Btw. the .res file doesn't contain the random
string.

Then I've changed the wrapper to call a different GCC_COLLECT

#! /bin/sh
echo $COLLECT_GCC >> /tmp/collect_gcc
echo "$@" >> /tmp/foobar
cp $(echo "$1"|sed 's/^.//') /tmp/input
COLLECT_GCC=/usr/bin/g++-wrapper /usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper2 "$@"|tee /tmp/output

the g++-wrapper was just a simple

#! /bin/sh
echo "$@" >> /tmp/foobarcollect
g++ "$@

The output was a long list of something like:

-xlto -c -fno-trapv -mmmx -msse -mtune=generic -march=x86-64 -O3 -fPIC -fexceptions -O3 -ffast-math -fno-strict-aliasing -fvisibility=hidden -D GCC -mmmx -msse -fPIC -D _REENT    RANT -shared -L /usr/lib/x86_64-linux-gnu -L /usr/lib/x86_64-linux-gnu -shared-libgcc -mtune=generic -march=x86-64 -dumpdir ./ -dumpbase mupen64plus-video-glide64mk2.so.ltrans    0 -fltrans -o /tmp/ccjdkQfg.ltrans0.ltrans.o /tmp/ccjdkQfg.ltrans0.o

The input already has the random name and the output just also receives it.
Interestingly there is already some earlier call:

@/tmp/ccjsmCwb.args

The content of this file is rather long. But the only line with the relevant
random string:

-fltrans-output-list=/tmp/ccjdkQfg.ltrans.out

My first guess is that it comes from ltrans_output_file.

All these files are stored in /tmp and this makes it unsafe when these were
not some kind of unique files. Otherwise on a parallel build (or another
user building on that machine), the output could be overwritten or collide.

Does anyone know if it maybe possible or feasible to drop these names from the
resulting file? They don't seem to be relevant.

Looking through the code of lto-wrapper makes it quite clear that these names
are only generated on WHOPR and partitioned lto runs. I've modified
debian/rules of mupen64plus-core and added following to
DEB_CFLAGS_MAINT_APPEND:

-flto-partition=none

I have to read a little bit how the partitioning might affect the build. The
random filenames seem to be gone now. *But* the debug files are still quite
different. The binaries are still different in the build-id and the debug link.

Regards,
Conchúr Navid



More information about the Reproducible-builds mailing list