Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 355861 - app-emulation/qemu-0.14.0 fail to build with gcc-4.5.2 with OOM condition
Summary: app-emulation/qemu-0.14.0 fail to build with gcc-4.5.2 with OOM condition
Status: RESOLVED OBSOLETE
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: Current packages (show other bugs)
Hardware: x86 Linux
: High normal with 1 vote (vote)
Assignee: Gentoo Toolchain Maintainers
URL:
Whiteboard:
Keywords:
: 369087 369427 401281 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-02-21 15:57 UTC by Andrew Savchenko
Modified: 2012-10-21 22:18 UTC (History)
7 users (show)

See Also:
Package list:
Runtime testing required: ---


Attachments
build.log (build.log,19.28 KB, text/plain)
2011-02-21 15:59 UTC, Andrew Savchenko
Details
environment (environment,138.30 KB, text/plain)
2011-02-21 15:59 UTC, Andrew Savchenko
Details
emerge --info (emerge.info,7.57 KB, text/plain)
2011-02-21 16:00 UTC, Andrew Savchenko
Details
result of $ emerge -aDNu qemu-kvm (qemu-kvm--emerge,17.34 KB, text/plain)
2011-06-13 19:58 UTC, Max Kresch
Details
result of $ emerge --info qemu-kvm (qemu-kvm--emerge-info,4.99 KB, text/plain)
2011-06-13 19:59 UTC, Max Kresch
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Savchenko gentoo-dev 2011-02-21 15:57:47 UTC
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.
Comment 1 Andrew Savchenko gentoo-dev 2011-02-21 15:59:45 UTC
Created attachment 263309 [details]
build.log
Comment 2 Andrew Savchenko gentoo-dev 2011-02-21 15:59:56 UTC
Created attachment 263311 [details]
environment
Comment 3 Andrew Savchenko gentoo-dev 2011-02-21 16:00:14 UTC
Created attachment 263313 [details]
emerge --info
Comment 4 Jorge Manuel B. S. Vicetto (RETIRED) Gentoo Infrastructure gentoo-dev 2011-02-21 19:49:44 UTC
Have you tried looking at the free output during the merge?
Comment 5 Andrew Savchenko gentoo-dev 2011-02-21 20:03:36 UTC
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.
Comment 6 Xavier Miller (RETIRED) gentoo-dev 2011-02-22 16:45:19 UTC
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.
> 

Comment 7 Andrew Savchenko gentoo-dev 2011-02-22 17:56:50 UTC
(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.
Comment 8 Xavier Miller (RETIRED) gentoo-dev 2011-02-22 18:45:14 UTC
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.
> 

Comment 9 walt 2011-03-18 12:25:18 UTC
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]);
Comment 10 walt 2011-03-19 16:23:37 UTC
See this bug report:

https://bugs.launchpad.net/gcc-linaro/+bug/714921
Comment 11 Vladimir 2011-03-23 10:22:41 UTC
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.
Comment 12 Anthony Basile gentoo-dev 2011-05-29 19:40:00 UTC
*** Bug 369087 has been marked as a duplicate of this bug. ***
Comment 13 SpanKY gentoo-dev 2011-06-07 04:20:45 UTC
*** Bug 369427 has been marked as a duplicate of this bug. ***
Comment 14 SpanKY gentoo-dev 2011-06-07 04:22:52 UTC
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 ...
Comment 15 Max Kresch 2011-06-13 19:58:51 UTC
Created attachment 276955 [details]
result of $ emerge -aDNu qemu-kvm
Comment 16 Max Kresch 2011-06-13 19:59:28 UTC
Created attachment 276957 [details]
result of $ emerge --info qemu-kvm
Comment 17 Max Kresch 2011-06-13 19:59:39 UTC
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.
Comment 18 Ryan Hill (RETIRED) gentoo-dev 2011-06-23 05:04:10 UTC
(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.
Comment 19 Sergei Trofimovich (RETIRED) gentoo-dev 2012-01-29 12:12:02 UTC
(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.
Comment 20 Doug Goldstein (RETIRED) gentoo-dev 2012-01-29 21:57:54 UTC
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.
Comment 21 Sergei Trofimovich (RETIRED) gentoo-dev 2012-01-30 05:58:56 UTC
*** Bug 401281 has been marked as a duplicate of this bug. ***
Comment 22 Sergei Trofimovich (RETIRED) gentoo-dev 2012-01-30 08:19:59 UTC
(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.
Comment 23 Sergei Trofimovich (RETIRED) gentoo-dev 2012-01-30 17:44:28 UTC
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
Comment 24 Ryan Hill (RETIRED) gentoo-dev 2012-07-15 05:52:58 UTC
can someone test the patches mike pointed to?
Comment 25 Doug Goldstein (RETIRED) gentoo-dev 2012-10-20 16:38:32 UTC
(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.