Hello, qemu-0.14.0 fails to compile with OOM: virtual memory exhausted: Cannot allocate memory make[1]: *** [translate.o] Error 1 make: *** [subdir-x86_64-softmmu] Error 2 I tried to reduce flags and to disable dangerous things: FEATURES="-distcc -ccache" MAKEOPTS="-j1" CFLAGS="-O2" CXXFLAGS="-O2" emerge qemu but it still fails. I have 2GB RAM, should be more that enough for single thread build: $ free total used free shared buffers cached Mem: 2063192 202320 1860872 0 38736 120480 -/+ buffers/cache: 43104 2020088 Swap: 1060252 57036 1003216 May be this is yet another gcc bug.
Created attachment 263309 [details] build.log
Created attachment 263311 [details] environment
Created attachment 263313 [details] emerge --info
Have you tried looking at the free output during the merge?
I have monitored build using htop. During the build process of some object files most CPU resources were utilized by kernel kworker threads, gcc RES memory size grows up to 1 GB, system became badly responsible. But eventually those object files were build until the build process strucks with translate.o, behaviour repeats as above, but gcc tried to consume more that 1.7 GB of memory and, apparently, was killed by OOM. I repeated checks several times with different CFLAGS and FEATURES, but it always dies at that object file build. I used Intel Atom N270 with 2GB of RAM and 2/2 memory split in the kernel.
It seems that 2 Gb is not enough. You need at least 3 Go, maybe 4. It compiled fine on my Atom netbook (with 1.5RAM + 1.5 swap) on i686, but the distcc server could not compile (it has 2 Go RAM + 0 swap). I Added 2 GO swap on my AMD64 machine, and distcc could run, and also the x86_64 build. Can't we add a memory limit check on the ebuild to warn if there is not enough RAM ? BTW I found that need of so much ram problematic... (In reply to comment #5) > I have monitored build using htop. > > During the build process of some object files most CPU resources were utilized > by kernel kworker threads, gcc RES memory size grows up to 1 GB, system became > badly responsible. But eventually those object files were build until the build > process strucks with translate.o, behaviour repeats as above, but gcc tried to > consume more that 1.7 GB of memory and, apparently, was killed by OOM. I > repeated checks several times with different CFLAGS and FEATURES, but it always > dies at that object file build. > > I used Intel Atom N270 with 2GB of RAM and 2/2 memory split in the kernel. >
(In reply to comment #6) > It seems that 2 Gb is not enough. You need at least 3 Go, maybe 4. > > It compiled fine on my Atom netbook (with 1.5RAM + 1.5 swap) on i686, but the > distcc server could not compile (it has 2 Go RAM + 0 swap). > > I Added 2 GO swap on my AMD64 machine, and distcc could run, and also the > x86_64 build. > > Can't we add a memory limit check on the ebuild to warn if there is not enough > RAM ? > > BTW I found that need of so much ram problematic... This is definitely abnormal, even libreoffice compiles on 512 MB of RAM (with -j1 at least). Looks like some memory leak in gcc, and it is just by accident that 4GB is enough for compilation of this object file to finish. By the way, I can't add memory up to 4 GB for none of my 3 Gentoo boxes due to hardware limitations.
I added swap and it went fine. My 2 machines are limited by ram < 2Gb, but with 2Gb swap, I could go around the memory problem. But: is the generated binary OK? (In reply to comment #7) > By the way, I can't add memory up to 4 GB for none of my 3 Gentoo boxes due to > hardware limitations. >
I git-bisected the qemu commit that triggers the gcc problem: commit c832e3de64f1069313fc0672087791cc3dd5b4d8 Author: Richard Henderson <rth@> Date: Mon Jan 10 19:23:47 2011 -0800 target-i386: Use deposit operation. Use this for assignment to the low byte or low word of a register. diff --git a/target-i386/translate.c b/target-i386/translate.c index c008450..7b6e3c2 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -274,16 +274,28 @@ static inline void gen_op_andl_A0_ffff(void) static inline void gen_op_mov_reg_v(int ot, int reg, TCGv t0) { + TCGv tmp; + switch(ot) { case OT_BYTE: + tmp = tcg_temp_new(); + tcg_gen_ext8u_tl(tmp, t0); if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) { - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 8); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); } else { - tcg_gen_deposit_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], t0, 8, 8); + tcg_gen_shli_tl(tmp, tmp, 8); + tcg_gen_andi_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], ~0xff00); + tcg_gen_or_tl(cpu_regs[reg - 4], cpu_regs[reg - 4], tmp); } + tcg_temp_free(tmp); break; case OT_WORD: - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], t0, 0, 16); + tmp = tcg_temp_new(); + tcg_gen_ext16u_tl(tmp, t0); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); + tcg_temp_free(tmp); break; default: /* XXX this shouldn't be reached; abort? */ case OT_LONG: @@ -311,9 +323,15 @@ static inline void gen_op_mov_reg_T1(int ot, int reg) static inline void gen_op_mov_reg_A0(int size, int reg) { + TCGv tmp; + switch(size) { case 0: - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16); + tmp = tcg_temp_new(); + tcg_gen_ext16u_tl(tmp, cpu_A0); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); + tcg_temp_free(tmp); break; default: /* XXX this shouldn't be reached; abort? */ case OT_LONG: @@ -311,9 +323,15 @@ static inline void gen_op_mov_reg_T1(int ot, int reg) static inline void gen_op_mov_reg_A0(int size, int reg) { + TCGv tmp; + switch(size) { case 0: - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_A0, 0, 16); + tmp = tcg_temp_new(); + tcg_gen_ext16u_tl(tmp, cpu_A0); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], tmp); + tcg_temp_free(tmp); break; default: /* XXX this shouldn't be reached; abort? */ case 1: @@ -397,7 +415,9 @@ static inline void gen_op_add_reg_im(int size, int reg, int32_t val) switch(size) { case 0: tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); + tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0); break; case 1: tcg_gen_addi_tl(cpu_tmp0, cpu_regs[reg], val); @@ -419,7 +439,9 @@ static inline void gen_op_add_reg_T0(int size, int reg) switch(size) { case 0: tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]); - tcg_gen_deposit_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0, 0, 16); + tcg_gen_ext16u_tl(cpu_tmp0, cpu_tmp0); + tcg_gen_andi_tl(cpu_regs[reg], cpu_regs[reg], ~0xffff); + tcg_gen_or_tl(cpu_regs[reg], cpu_regs[reg], cpu_tmp0); break; case 1: tcg_gen_add_tl(cpu_tmp0, cpu_regs[reg], cpu_T[0]);
See this bug report: https://bugs.launchpad.net/gcc-linaro/+bug/714921
QEMU 0.14.0 hardly compiles on my AMD64 laptop with 1,5 GB RAM + 1GB swap with MAKEOPTS="-j1". The most consuming files for the compilation process are those with "translate.o" name.
*** Bug 369087 has been marked as a duplicate of this bug. ***
*** Bug 369427 has been marked as a duplicate of this bug. ***
upstream gcc seems to have fixes we can grab: http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00193.html http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00255.html maybe only the first will fix things for us here though ...
Created attachment 276955 [details] result of $ emerge -aDNu qemu-kvm
Created attachment 276957 [details] result of $ emerge --info qemu-kvm
Not 100% sure I'm having the same problem, but I thought I'd post and let you (smart people) sort wheat from chaff. If this is all chaff, I apologize. Basically, on an amd64 laptop with 2GB RAM, no swap, and gcc-4.5.2, I get a different error message on compile of translate.o. I've attached "qemu-kvm-emerge" (result of $ emerge -aDNu qemu-kvm) and "qemu-kvm-emerge-info" (result of $ emerge --info qemu-kvm). I'm happy to provide further information if it's of use, but be forewarned that you'll probably have to provide fairly detailed instructions.
(In reply to comment #14) > upstream gcc seems to have fixes we can grab: > http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00193.html > http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00255.html > > maybe only the first will fix things for us here though ... I'm not sure. These guys aren't using -g.
(In reply to comment #18) > (In reply to comment #14) > > upstream gcc seems to have fixes we can grab: > > http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00193.html > > http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00255.html > > > > maybe only the first will fix things for us here though ... > > I'm not sure. These guys aren't using -g. The qemu's buildsystem silently appends -g in it's internals. I'm about to commit removal of '-g' from ./configure to qemu{,-kvm}-9999. + # drop '-g' by default as it tends to eat + # A LOT (~2GB) of ram for each job #355861 + sed -e 's/CFLAGS="-g $CFLAGS"/CFLAGS="$CFLAGS"/g' \ + -i configure || die With the fix things became bearable: ~300MB RAM per make job is enough to build every target. Build time shortened from 74 minutes down to 26 minutes on my box. Some crazy stats (gcc-4.5.3-r2) for mips64el/translate.c: - with -g enabled gcc generates translate.S of size 78MB(!) [ gas ran alone tries to chew it it eats ~800MB of RAM. gcc ran with -pipe can eat more than 1.5GB easily ] - with -g disabled gcc generates translate.S of size 1.8MB '-g' enabled translate.S contains a ton of local labels (pointing to the same place), so i guess it's one of the reasons why gcc/as need a lot of runtime info when they Do Stuff. Hope that helps.
Except that -g adds a lot more information than you may think and is actually necessary when QEMU runs any of the guest code through the TCG and then executes it. Removing out the -g will actually break you QEMU installation.
*** Bug 401281 has been marked as a duplicate of this bug. ***
(In reply to comment #20) > Except that -g adds a lot more information than you may think and is actually > necessary when QEMU runs any of the guest code through the TCG and then > executes it. Removing out the -g will actually break you QEMU installation. Interesting. Sounds very fragine and unportable. AFAIU TCG is a runtime code generator. It takes intermediate representation (IR) operations and generates target code (or interprets it via TCI). $target-dis.c (with help of bfd?) and target-$arch/translate.c are responsible for IR (and basic block?) generation from target's native machine code. Much like valgrind does. Where does '-g' takes place here? For what targets and in what modes droppping '-g' should break? Do they need gebug info at compiletime or runtime? Portage strips binaries at runtime and i haven't found anything suspicious neither in code nor in ldscripts. With -g dropped qemu-kvm-9999 is still able to boot i386/x86_64 machines (both with -kvm/-no-kvm). Thanks.
Upstream also suggested to add '-fno-var-tracking' to CFLAGS to workaroung amount of generated debug info. As for '-g' flag nobody on #qemu told me about it's usefullness. The sole comment I've got is: > 20:07:48 < pbrook> slyfox: I'm pretty sure any -g requirement is either complete fiction or some subtle gcc bug
can someone test the patches mike pointed to?
(In reply to comment #24) > can someone test the patches mike pointed to? You can probably close this out since we're working around this in other ways and now we're pushing for gcc 4.6.