http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50337
Bug #: 50337
Summary: -ftree-dse performs wrong elimination on
electric-fence
Classification: Unclassified
Product: gcc
Version: 4.6.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: [email protected]
ReportedBy: [email protected]
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc-4.6.real
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6.1/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.6.1-9ubuntu2' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr
--program-suffix=-4.6 --enable-shared --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin
--enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686
--with-tune=generic --enable-checking=release --build=i686-linux-gnu
--host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.1 (Ubuntu/Linaro 4.6.1-9ubuntu2)
$ gcc -O2 -g -Wall efence.i -lpthread
efence.c: In function ‘stringErrorReport’:
efence.c:944:2: warning: return makes pointer from integer without a cast
[enabled by default]
efence.c: In function ‘vprint’:
efence.c:1135:5: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
efence.c:1156:6: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
efence.c:1165:12: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
efence.c:1178:6: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
efence.c:1189:4: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
efence.c: In function ‘printNumber’:
efence.c:1119:8: warning: ignoring return value of ‘write’, declared with
attribute warn_unused_result [-Wunused-result]
$ ./a.out
iteration 0: size 29
Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.
[...]
iteration 233: size 9007
Segmentation fault (core dumped)
(The exact number of iterations may vary. Since this is entering infinite
recursion, you might want to have a ulimit in place if trying this out.)
In gdb, I can see that the problem is that internalUse is not set to 1 in the
allocateMoreSlots function while recursively calling malloc, and indeed that
assignment has been optimised out:
(gdb) disas /rm memalign
[...]
418 static void
419 allocateMoreSlots(void)
420 {
421 size_t newSize = allocationListSize + bytesPerPage;
0x080498b3 <+627>: a1 94 c0 04 08 mov 0x804c094,%eax
0x080498b8 <+632>: 8b 3d 8c c0 04 08 mov 0x804c08c,%edi
0x080498c8 <+648>: 01 c7 add %eax,%edi
422 void * newAllocation;
423 void * oldAllocation = allocationList;
0x080498be <+638>: 8b 35 88 c0 04 08 mov 0x804c088,%esi
424
425 Page_AllowAccess(allocationList, allocationListSize);
0x080498c4 <+644>: 89 44 24 04 mov %eax,0x4(%esp)
0x080498ca <+650>: 89 34 24 mov %esi,(%esp)
0x080498cd <+653>: e8 be f5 ff ff call 0x8048e90 <Page_AllowAccess>
426 noAllocationListProtection = 1;
427 internalUse = 1;
428
429 newAllocation = malloc(newSize);
0x080498d2 <+658>: 89 3c 24 mov %edi,(%esp)
0x080498d5 <+661>: e8 86 fb ff ff call 0x8049460 <malloc>
0x080498e8 <+680>: 89 c5 mov %eax,%ebp
Adding -fno-tree-dse to the compiler flags works around this bug. efence.i
attached (which is basically a concatenation of efence.h, efence.c, page.c,
print.c, and tstheap.c from the electric-fence 2.1.16 package in Debian).