This appears to be an issue with gcc 3.4.4 optimization on pentium4
architecture. I am building a modified version of xv ("qxv") and am seeing qxv
crash due to a segfault in handleButtonEvent (the bzip2'd preprocessed file of
xvevent.c is attached, where this function is defined). Simply running qxv
(with or without command line arguments) and clicking on the main window (right
or left click) causes the segfault.
I'm working in a Cygwin environment with gcc 3.4.4; I do not have this problem
with the current Cygwin gcc package (gcc 3.4.1, 3.3.1, or 3.3.3), but can't use
that version for other reasons.
Unfortunately, it has turned out to be really tricky to reduce the problem to a
simpler form; most changes I try to make to handleButtonEvent to strip out the
qxv-related stuff make the segfault go away, so there doesn't seem to be much I
can do to make a simple test case. Sorry about that. I hope the preprocessed
file I've attached is sufficient, even though you won't be able to (easily) run
the application and see the error for yourself. I can produce the assembly file
for xvevent.i if you need it.
Here's my output from `gcc -v`:
Reading specs from /usr/local/lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: ../gcc/configure --verbose --enable-languages=c --disable-
win32-registry --with-as=/usr/local/bin/as --with-ld=/usr/local/bin/ld
Thread model: single
gcc version 3.4.4 20041123 (prerelease)
The symptoms of my problem are as follows. Note that line numbers are for the
attached xvevent.i file:
(*) qxv receives segfault at line 11179 when you click on its main window.
(*) Removing 'static' from handleButtonEvent or passing "-fno-inline" to gcc
makes the segfault go away.
(*) fprintf (line 11175) shows but_event is NULL right before the segfault, but
at handleButtonEvent call site (line 10283), the argument is not NULL. If you
move the fprintf line to line 11173, it prints out a non-NULL event argument
and
the segfault goes away. If you remove the fprintf line (the original condition
of the code), the segfault remains.
(*) Using gdb, event is non-NULL before line 11174, but becomes NULL somewhere
in that line (as described below), apparently causing the segfault.
(*) The assembly where the error appears to take place is (from gdb):
Dump of assembler code for function handleButtonEvent:
0x004686ee <handleButtonEvent+0>: push %ebp
0x004686ef <handleButtonEvent+1>: mov %esp,%ebp
0x004686f1 <handleButtonEvent+3>: push %eax
0x004686f2 <handleButtonEvent+4>: mov $0xfa4,%eax
0x004686f7 <handleButtonEvent+9>: call 0x4e1d10 <_alloca>
0x004686fc <handleButtonEvent+14>: mov %ebx,0xfffffff4(%ebp)
0x004686ff <handleButtonEvent+17>: mov %esi,0xfffffff8(%ebp)
0x00468702 <handleButtonEvent+20>: mov %edi,0xfffffffc(%ebp)
0x00468705 <handleButtonEvent+23>: mov 0xfa4(%esp),%eax
0x0046870c <handleButtonEvent+30>: mov %edx,0xfffff12c(%ebp)
0x00468712 <handleButtonEvent+36>: mov %eax,%ebx
0x00468714 <handleButtonEvent+38>: mov (%edx),%eax
At handleButtonEvent+36, event=0x22eab0; after executing that instruction (we
are now at handleButtonEvent+38), event=0x0 (gdb says event is stored in
register ebx).
(*) Changing either the "-O2" (to "-O1" or removing) or the "-march=pentium4"
(to "pentium3" or removing) flags to gcc makes the segfault go away.
My admittedly inexperienced assessment is that gcc is doing something wrong
when
inlining handleButtonEvent (making it non-static or forcing gcc to not inline
removes the problem) with O2 optimization on pentium4.
--
Summary: [C] gcc 3.4.4 zeroes inline function argument with "-O2
-march=pentium4"
Product: gcc
Version: 3.4.4
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: thrall at vss dot fsi dot com
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-cygwin
GCC host triplet: i686-pc-cygwin
GCC target triplet: i686-pc-cygwin
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18723