gcc-linaro uses an unreasonable amount of memory to compile qemu on armel
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Linaro GCC |
Fix Released
|
Medium
|
Richard Sandiford | ||
gcc-4.5 (Debian) |
Fix Released
|
Unknown
|
|||
gcc-4.5 (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
I've been trying to sort out why qemu-linaro was failing to build on armel; the build logs have been showing unreasonable memory consumption - e.g., an OOM on a buildd with 30GB of swap. The same build did not run out of memory with gcc-4.4 on armel (I can reliably build the same code with ulimit -S -v $((1024*1024)) using gcc-4.4); it does not run out of memory when using the *same* gcc-4.5 as an x86->armel cross-compiler (requires a ulimit of 3250MiB in my tests); and it does not run out of memory on armel with gcc-4.5 if I pass -fno-var-tracking (completes with a ulimit of 320MiB).
But if I build with -O2 -g natively on armel and leave var-tracking on, it OOMs even with a ulimit of 5GiB.
This is more than a 16-fold increase in memory consumption from var tracking. Furthermore, the memory usage seems to show a dramatic spike right before the failure. Here's the memory usage immediately before the OOM:
# free
total used free shared buffers cached
Mem: 496996 456488 40508 0 172 7616
-/+ buffers/cache: 448700 48296
Swap: 6032396 1411232 4621164
# ps u 2642
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2642 15.3 81.9 1615736 407472 ttyO2 T 22:40 11:00 /usr/lib/gcc/ar
#
This is 23 minutes into the build. But with a ulimit of 5GiB, within seconds I get the inevitable:
virtual memory exhausted: Cannot allocate memory
This is sudden enough that I'm convinced there's some kind of bug here; I can't imagine why gcc should need to allocate > 3GB of memory at a go.
I'll post a copy shortly of the preprocessed source used to reproduce this, plus the commandline that triggers it. I'll also see what I can root out with valgrind and/or strace; though at 24minutes an iteration it'll take a while yet.
Related branches
- Andrew Stubbs (community): Approve
-
Diff: 322 lines (+156/-19) (has conflicts)2 files modifiedChangeLog.linaro (+29/-0)
gcc/dwarf2out.c (+127/-19)
- Ramana Radhakrishnan (community): Approve
-
Diff: 310 lines (+149/-19) (has conflicts)2 files modifiedgcc/ChangeLog (+28/-0)
gcc/dwarf2out.c (+121/-19)
Changed in gcc-linaro: | |
assignee: | nobody → Richard Sandiford (rsandifo) |
Changed in gcc-linaro: | |
status: | Triaged → In Progress |
Changed in gcc-4.5 (Ubuntu): | |
status: | New → Confirmed |
Changed in gcc-4.5 (Debian): | |
status: | Unknown → New |
Changed in gcc-4.5 (Debian): | |
status: | New → Confirmed |
Changed in gcc-linaro: | |
status: | In Progress → Fix Committed |
Changed in gcc-linaro: | |
status: | Fix Committed → Fix Released |
Changed in gcc-4.5 (Debian): | |
status: | Confirmed → Fix Released |
Nonreduced preprocessed source attached. Build with this command (natively on arm) to reproduce:
/usr/lib/ gcc/arm- linux-gnueabi/ 4.5.2/cc1 -quiet gcc-oom.i -quiet -dumpbase translate.c -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -auxbase-strip translate.o -g -O2 -Werror -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wendif-labels -Wwrite-strings -Wmissing- prototypes -Wmissing- include- dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored- qualifiers -Wold-style- declaration -Wold-style- definition -Wtype-limits -fno-strict- aliasing -fstack-protector -o translate.s
$ gcc --version
gcc (Ubuntu/Linaro 4.5.2-2ubuntu1) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
The OOM comes while cc1 is writing the output file out to disk; strace shows a large number of writes interspersed with calls to mmap2() requesting 1MiB allocations for every ~680-748KiB output to the file. By the time of the OOM (with ulimit now raised to 6GiB), the output file has grown to 174MiB here; but that only accounts for something like 260MiB, nothing close to the ulimit. So I'm still not sure what's going on here.