Bug 85704 - [8/9 Regression] cc1 run out of memory when it compile
Summary: [8/9 Regression] cc1 run out of memory when it compile
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 8.1.0
: P2 normal
Target Milestone: 8.3
Assignee: Jakub Jelinek
URL:
Keywords: memory-hog
Depends on:
Blocks:
 
Reported: 2018-05-08 18:33 UTC by Haruue Icymoon
Modified: 2018-08-11 19:43 UTC (History)
2 users (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work: 7.3.0
Known to fail: 8.1.0
Last reconfirmed: 2018-05-09 00:00:00


Attachments
The output of strace (97.93 KB, text/plain)
2018-05-08 18:33 UTC, Haruue Icymoon
Details
The preprocessed source, compressed with gzip (205.62 KB, application/x-gzip)
2018-05-08 18:49 UTC, Haruue Icymoon
Details
gcc9-pr85704.patch (1.58 KB, patch)
2018-07-23 14:28 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Haruue Icymoon 2018-05-08 18:33:43 UTC
Created attachment 44089 [details]
The output of strace

I run out of memory when I try to build linux-usermode 4.16.7 with gcc 8.1.0.


* The operation to reproduce the problem: 
wget http://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.16.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/patch-4.16.7.xz
tar -Jxf linux-4.16.tar.xz
xz -d patch-4.16.7.xz
cd linux-4.16/
patch -p1 -i ../patch-4.16.7
make ARCH=um defconfig
ulimit -m 1500000 -v 1500000
make ARCH=um

Then, when it compiles the arch/um/drivers/ubd_kern.c, GCC got into stuck and exhausts 1.5GB memory in little time.


* Source code of arch/um/drivers/ubd_kern.c in linux kernel tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/um/drivers/ubd_kern.c


* The actual command invoked is following:
gcc -Wp,-MD,arch/um/drivers/.ubd_kern.o.d \
	-nostdinc \
	-isystem \
	/usr/lib/gcc/x86_64-pc-linux-gnu/8.1.0/include \
	-I./arch/um/include \
	-I./arch/um/include/generated \
	-I./include \
	-I./arch/um/include/uapi \
	-I./arch/um/include/generated/uapi \
	-I./include/uapi \
	-I./include/generated/uapi \
	-include \
	./include/linux/kconfig.h \
	-D__KERNEL__ \
	-m64 \
	-I./arch/x86/um \
	-I./arch/x86/include \
	-I./arch/x86/include/uapi \
	-I./arch/x86/include/generated \
	-I./arch/x86/include/generated/uapi \
	-Wall \
	-Wundef \
	-Wstrict-prototypes \
	-Wno-trigraphs \
	-fno-strict-aliasing \
	-fno-common \
	-fshort-wchar \
	-Werror-implicit-function-declaration \
	-Wno-format-security \
	-std=gnu89 \
	-fno-PIE \
	-mcmodel=large \
	-fno-builtin \
	-m64 \
	-funit-at-a-time \
	-D__arch_um__ \
	-I./arch/um/include/shared \
	-I./arch/x86/um/shared \
	-I./arch/um/include/shared/skas \
	-Dvmap=kernel_vmap \
	-Dlongjmp=kernel_longjmp \
	-Dsetjmp=kernel_setjmp \
	-Din6addr_loopback=kernel_in6addr_loopback \
	-Din6addr_any=kernel_in6addr_any \
	-Dstrrchr=kernel_strrchr \
	-D_LARGEFILE64_SOURCE \
	-Derrno=kernel_errno \
	-Dsigprocmask=kernel_sigprocmask \
	-Dmktime=kernel_mktime \
	-fno-delete-null-pointer-checks \
	-Wno-frame-address \
	-Wno-format-truncation \
	-Wno-format-overflow \
	-Wno-int-in-bool-context \
	-Os \
	-Wno-maybe-uninitialized \
	--param=allow-store-data-races=0 \
	-DCC_HAVE_ASM_GOTO \
	-Wframe-larger-than=1024 \
	-fno-stack-protector \
	-Wno-unused-but-set-variable \
	-Wno-unused-const-variable \
	-fno-omit-frame-pointer \
	-fno-optimize-sibling-calls \
	-fno-var-tracking-assignments \
	-g \
	-Wdeclaration-after-statement \
	-Wno-pointer-sign \
	-fno-strict-overflow \
	-fno-merge-all-constants \
	-fmerge-constants \
	-fno-stack-check \
	-fconserve-stack \
	-Werror=implicit-int \
	-Werror=strict-prototypes \
	-Werror=date-time \
	-Werror=incompatible-pointer-types \
	-Werror=designated-init \
	-Wno-packed-not-aligned \
	-DKBUILD_BASENAME='"ubd_kern"' \
	-DKBUILD_MODNAME='"ubd"' \
	-c -o \
	arch/um/drivers/ubd_kern.o \
	arch/um/drivers/ubd_kern.c;
	

I feel sorry because I know little about gcc implementation. I attached the strace output of above gcc command. It seem that gcc just mmap more and more memory before memory run out.

And everything is OK in GCC 7.3.1. 

Is this a bug of gcc or just some problem in the kernel code?
Comment 1 Andrew Pinski 2018-05-08 18:35:37 UTC
Can you provide the preprocessed source (that is if you add -save-temps is the memory usage high)?
Comment 2 Haruue Icymoon 2018-05-08 18:49:40 UTC
Created attachment 44090 [details]
The preprocessed source, compressed with gzip

With -save-temps, It generated preprocessed source normally, no diff with the output of -E.

But the assembler source and elfs can't be generated normally.

The size of preprocessed source is larger than 1000KB so I gzip it.
Comment 3 Haruue Icymoon 2018-05-09 04:20:29 UTC
* More Information

Tested the gcc that build with following commands can reproduce this problem.

wget https://ftp.gnu.org/gnu/gcc/gcc-8.1.0/gcc-8.1.0.tar.xz
tar -Jxf gcc-8.1.0.tar.xz
./configure --enable-languages=c --disable-multilib
make
make install


Then test it with

ulimit -m 1500000 -v 1500000
/usr/local/bin/gcc ubd_kern.i
Comment 4 Richard Biener 2018-05-09 07:38:03 UTC
Confirmed with just -Os.  We're stuck in parsing.

Run till exit from #0  0x0000000000874c8c in output_pending_init_elements (
    all=1, braced_init_obstack=0x7fffffffc000)
    at /space/rguenther/src/svn/gcc-8-branch/gcc/c/c-typeck.c:9392
...
Comment 5 Jakub Jelinek 2018-07-23 11:48:21 UTC
Started with r258497 aka PR46921 fix.
Comment 6 Jakub Jelinek 2018-07-23 12:14:32 UTC
Reduced testcase for -Os:

struct C { struct {} c; };
struct D { int d; struct C e; int f; };

void
foo (struct D *x)
{
  *x = (struct D) { .e = (struct C) { .c = {} } };
}
Comment 7 Jakub Jelinek 2018-07-23 14:28:16 UTC
Created attachment 44425 [details]
gcc9-pr85704.patch

Untested fix.  If people use thousands of consecutive zero sized fields in structures, this could be compile time problematic, but we unfortunately don't have any sort of monotonically increasing ids for FIELD_DECLs within the same structure.
Comment 8 Jakub Jelinek 2018-07-26 11:20:24 UTC
GCC 8.2 has been released.
Comment 9 Jakub Jelinek 2018-08-01 09:11:03 UTC
Author: jakub
Date: Wed Aug  1 09:10:31 2018
New Revision: 263198

URL: https://gcc.gnu.org/viewcvs?rev=263198&root=gcc&view=rev
Log:
	PR c/85704
	* c-typeck.c (init_field_decl_cmp): New function.
	(output_pending_init_elements): Use it for field comparisons
	instead of pure bit_position comparisons.

	* gcc.c-torture/compile/pr85704.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/pr85704.c
Modified:
    trunk/gcc/c/ChangeLog
    trunk/gcc/c/c-typeck.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 Jakub Jelinek 2018-08-01 09:36:05 UTC
Author: jakub
Date: Wed Aug  1 09:35:34 2018
New Revision: 263199

URL: https://gcc.gnu.org/viewcvs?rev=263199&root=gcc&view=rev
Log:
	PR c/85704
	* c-typeck.c (init_field_decl_cmp): New function.
	(output_pending_init_elements): Use it for field comparisons
	instead of pure bit_position comparisons.

	* gcc.c-torture/compile/pr85704.c: New test.

Added:
    branches/gcc-8-branch/gcc/testsuite/gcc.c-torture/compile/pr85704.c
Modified:
    branches/gcc-8-branch/gcc/c/ChangeLog
    branches/gcc-8-branch/gcc/c/c-typeck.c
    branches/gcc-8-branch/gcc/testsuite/ChangeLog
Comment 11 Jakub Jelinek 2018-08-11 19:43:24 UTC
Fixed.