SOLVED Debian Lenny issue (was Re: Bootstrap GCC Pass 1 or 2? (was Re: Resolution))
Greg Schafer
gschafer at zip.com.au
Sun Sep 2 18:56:51 MDT 2007
Alexander E. Patrakov wrote:
> All these "Invalid argument" errors indicate that either parameters are
> passed incorrectly to glibc functions, or the return codes of glibc
> functions are misinterpreted. The guess is that gcc stage1 doesn't
> understand Debian's multilib setup and picks up wrong files in
> /usr/include (and thus, stage2 is miscompiled). One more confirmation of
> this idea: if you don't add --disable-libmudflap, you get a compilation
> error about redeclaration of something with a different size.
>
> Conclusion: Debian Lenny x86 multilib setup (which is clearly a huge
> deviation from upstream gcc) is not going to be supported by any native
> build method. The fact that "non-bootstrap of gcc pass1" works is pure luck.
Ok, finally got around to looking at this problem. Indeed, it's a fscking
nightmare. Allow me to explain..
The "Invalid argument" string can be traced back to the errno handling
stuff in libiberty, then to gcc.c where the perror_with_name() function is
called by the pfatal_with_name() function. pfatal_with_name() is called
from within the load_specs() function here:
/* Open and stat the file. */
desc = open (filename, O_RDONLY, 0);
if (desc < 0)
pfatal_with_name (filename);
if (stat (filename, &statbuf) < 0)
pfatal_with_name (filename);
A strace log shows what is happening:
access("/temptools/src/gcc-build/gcc/specs", R_OK) = 0
open("/temptools/src/gcc-build/gcc/specs", O_RDONLY) = 3
write(2, "xgcc: ", 6) = 6
write(2, "/temptools/src/gcc-build/gcc/spe"..., 52) = 52
write(2, "\n", 1) = 1
exit_group(1)
But hang on, that makes no sense! The file is definitely there, but the
open() call has failed for no apparent reason. WTF? Ok, it's clear
something deep in the guts of libc is majorly broken here.
Further investigation reveals Debian Lenny does some (possibly weird)
stuff with the multilib Glibc include dirs. Essentially, it's a 32-bit
host so the Glibc 32-bit headers are naturally in /usr/include. But then
they've gone and stuck the 64-bit Glibc headers into
/usr/include/x86_64-linux-gnu.
With that information in hand, it now becomes clear why the build is so
deeply screwed. Basically, the stage2 gcc was linked against a 64-bit libc
but compiled against 32-bit libc headers. Arghhh! ie: the stage1 gcc (used
to compile stage2 gcc) doesn't know to look in
/usr/include/x86_64-linux-gnu for it's headers. I made the the build
succeed by adding `-isystem /usr/include/x86_64-linux-gnu' to BOOT_CFLAGS.
Therefore, I think Alex's analysis is mostly correct. ie: it's a
Debian-only 32-bit host multilib issue. Specifically, it's the method they
use to set up the include dirs on a 32-bit host. But frankly, I don't know
enough about multilib to judge whether this obviously non-standard setup
is kosher or not. However, it does make sense and I can see why they've
done it. In a typical 64-bit multilib host setup, this kind of header
arrangement is not needed because the 64-bit Glibc headers are 32-bit
compatible (at least I think that's the case, not sure..)
Anyhoo, at least we now understand the issue and have a workaround. I need
to think more about the big picture and whether we need to worry about
this unusual host scenario.
BTW, some of the above core issues are touched upon here:
http://www.lotterer.net/blog/en/78
Regards
Greg
--
http://www.diy-linux.org/
More information about the lfs-dev
mailing list