Bug 46468 - enabling -fomit-frame-pointer by default breaks Wine
Summary: enabling -fomit-frame-pointer by default breaks Wine
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-11-13 22:28 UTC by austinenglish
Modified: 2011-07-29 18:55 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
bad preprocessed file (220.53 KB, application/x-bzip)
2011-06-29 02:20 UTC, austinenglish
Details
good preproccessed file (221.68 KB, application/x-bzip)
2011-06-29 02:20 UTC, austinenglish
Details

Note You need to log in before you can comment on or make changes to this bug.
Description austinenglish 2010-11-13 22:28:44 UTC
I've noticed lately that 'winetricks -q fm20' fails on my machine. I finally got around to running an svn bisect:

=============================================
Regression found!
Last good revision: r163193
First bad revision:
------------------------------------------------------------------------
r163196 | hjl | 2010-08-12 09:39:37 -0700 (Thu, 12 Aug 2010) | 16 lines

Turn on -fomit-frame-pointer by default for 32bit Linux/x86.

2010-08-12  H.J. Lu  <hongjiu.lu@intel.com>
	    Uros Bizjak  <ubizjak@gmail.com>

	* config.gcc: Handle --enable-frame-pointer.

	* configure.ac: Add --enable-frame-pointer.
	* configure: Regenerated.

	* config/i386/i386.c (USE_IX86_FRAME_POINTER): Default to 0.
	(override_options): If not configured with --enable-frame-pointer,
	enable -fomit-frame-pointer (but not for TARGET_MACHO or when
	optimizing for size), -fasynchronous-unwind-tables and
	-maccumulate-outgoing-args by default.

=============================================

so, I tried compiling wine with -fno-omit-frame-pointer, still fails. The only way to get a working wine was to compile gcc with --enable-frame-pointer.

The wine failure isn't too helpful:
$ wine /home/austin/.wine/dosdevices/c:/winetrickstmp/setup /qt
wine client error:3b: write: Bad file descriptor
err:seh:raise_exception Unhandled exception code c0000005 flags 0 addr 0x7dd247be
wine client error:3b: write: Bad file descriptor

however, the bug seems to be gcc producing bad code unless --enable-frame-pointer is used.

-- 
-Austin
Comment 1 Andrew Pinski 2010-11-13 22:46:08 UTC
So compiling wine with -fomit-frame-pointer creates a broken wine?  Can you try to find a small testcase.  Try first by bi-secting the object files.
Comment 2 Richard Biener 2010-11-14 10:46:39 UTC
I think they require a FP for unwinding.  But indeed -fno-omit-frame-pointer
should work - can you check what code differences occur with -fno-omit-frame-pointer vs. --enable-frame-pointer?
Comment 3 H.J. Lu 2010-11-14 15:03:09 UTC
It sounds like Wine doesn't use unwind library provided by
gcc to unwind the Linux stack. When Wine unwinds Linux
stack, it has to use the gcc unwind library, NOT Windows
unwind library, to unwind Linux stack.
Comment 4 marcus 2010-11-20 14:02:47 UTC
we use dwarf2 for unwinding.

the code should work with omit-frame-pointer too, we have some issues.

(Steam required no-omit as it hooked functions, but for this we have hooking now.)

Have to test it myself.
Comment 5 marcus 2010-11-25 08:12:28 UTC
i can reproduce this.

I will try to bisect which file of wine gets miscompiled to get a smaller testcase.
Comment 6 marcus 2010-11-25 10:01:26 UTC
first wine search converged on ntdll.dll.so being miscompiled (as i expected to some degree).

i will tomorrow focus on the specific object files.
Comment 7 marcus 2010-11-26 07:26:56 UTC
.o hunting converged on dlls/ntdll/thread.o

however:
$ diff -u bad.lst good.lst
--- bad.lst     2010-11-26 08:25:05.000000000 +0100
+++ good.lst    2010-11-26 08:25:12.000000000 +0100
@@ -1,5 +1,5 @@

-bad/thread.o:     file format elf32-i386
+good/thread.o:     file format elf32-i386


 Disassembly of section .text:
$ 

testing now unwinding flags...
Comment 8 marcus 2010-11-26 07:31:39 UTC
when I add 
-fno-omit-frame-pointer -fno-asynchronous-unwind-tables
it goes back to the "good" behaviour.
Comment 9 marcus 2010-11-28 14:55:31 UTC
(gdb) bt
#0  0xffffe425 in __kernel_vsyscall ()
#1  0xf7d1eb46 in kill () from /lib/libc.so.6
#2  0x7efab485 in server_protocol_error (err=0x7efcfe71 "write errnp=%d, reqfd=%d") at /home/marcus/projects/wine/dlls/ntdll/server.c:164
#3  0x7efab881 in send_request (req_ptr=0x6fd874) at /home/marcus/projects/wine/dlls/ntdll/server.c:215
#4  wine_server_call (req_ptr=0x6fd874) at /home/marcus/projects/wine/dlls/ntdll/server.c:289
#5  0x7efb1c10 in NtCreateEvent (EventHandle=0x6fd96c, DesiredAccess=2031619, attr=0x6fd950, type=NotificationEvent, InitialState=0 '\000')
    at /home/marcus/projects/wine/dlls/ntdll/sync.c:278
#6  0x7ed992bc in start_debugger_atomic (epointers=0x6fd9ac) at /home/marcus/projects/wine/dlls/kernel32/except.c:369
#7  UnhandledExceptionFilter (epointers=0x6fd9ac) at /home/marcus/projects/wine/dlls/kernel32/except.c:456
#8  0x7efc1ece in __wine_exception_handler (record=0x6fddf8, frame=0x6fea90, context=0x6fdb2c, pdispatcher=0x6fda80) at /home/marcus/projects/wine/dlls/winecrt0/exception.c:90
#9  0x7efac825 in call_exception_handler () from /usr/bin/../lib/wine/ntdll.dll.so
#10 0x7efac7f7 in EXC_CallHandler () from /usr/bin/../lib/wine/ntdll.dll.so
#11 0x7efaca2e in call_stack_handlers (rec=0x6fddf8, context=0x6fdb2c, first_chance=1) at /home/marcus/projects/wine/dlls/ntdll/signal_i386.c:606
#12 raise_exception (rec=0x6fddf8, context=0x6fdb2c, first_chance=1) at /home/marcus/projects/wine/dlls/ntdll/signal_i386.c:684
#13 0x7efaea0d in NtRaiseException (rec=0x6fddf8, context=0x6fdb2c, first_chance=1) at /home/marcus/projects/wine/dlls/ntdll/signal_i386.c:2394
#14 0x7efaeb14 in raise_segv_exception (rec=0x6fddf8, context=0x6fdb2c) at /home/marcus/projects/wine/dlls/ntdll/signal_i386.c:1720
#15 0xdeadbabe in ?? ()
#16 0x7dc812c5 in ?? () from /lib/libgcc_s.so.1
#17 0x7dc816ea in _Unwind_ForcedUnwind () from /lib/libgcc_s.so.1
#18 0xf7e6d032 in _Unwind_ForcedUnwind () from /lib/libpthread.so.0
#19 0xf7e6aa97 in __pthread_unwind () from /lib/libpthread.so.0
#20 0xf7e64a5e in pthread_exit () from /lib/libpthread.so.0
#21 0x7efb574b in exit_thread (status=5) at /home/marcus/projects/wine/dlls/ntdll/thread.c:369
#22 0x7efaee2d in RtlExitUserThread (status=5) at /home/marcus/projects/wine/dlls/ntdll/signal_i386.c:2488
#23 0x7edcf8b4 in ExitThread (code=5) at /home/marcus/projects/wine/dlls/kernel32/thread.c:155
#24 0x7dca7879 in ?? ()
#25 0x00000005 in ?? ()
#26 0x00000000 in ?? ()

(the kill a kill(gettid(),SIGSTOP) from me.)


So we basically exited our thread, closed the fd already ... and crash during the final unwinding. The crash wants to attach the debugger which does a server call which of course breaks as we jhave no server connetion anymore.
Comment 10 H.J. Lu 2010-11-28 15:23:22 UTC
(In reply to comment #9)
> 
> 
> So we basically exited our thread, closed the fd already ... and crash during

What caused the crash?

> the final unwinding. The crash wants to attach the debugger which does a server
> call which of course breaks as we jhave no server connetion anymore.

If crash is independent of -fno-omit-frame-pointer, it is a bug
in wine unwinder.
Comment 11 marcus 2010-11-28 19:31:27 UTC
it is unclear. ... it seems to crash in libgcc_s.so.1 (both the installed 4.5 and the built 4.6 trunk versuon) during this pthread_exit unwinding.

behaviour changes if thread.o is built with -fasynchronous-unwind-tables . then it will not crash

(i guess it seems to unwind over the thread.o functions and fails if the info is not there)
Comment 12 marcus 2010-11-28 19:31:58 UTC
the gcc or glibc unwinding is in use, not wine's if I take it correctly from the bakctrace.
Comment 13 H.J. Lu 2010-11-28 19:47:02 UTC
(In reply to comment #11)
> it is unclear. ... it seems to crash in libgcc_s.so.1 (both the installed 4.5
> and the built 4.6 trunk versuon) during this pthread_exit unwinding.
> 
> behaviour changes if thread.o is built with -fasynchronous-unwind-tables . then
> it will not crash
> 

Why isn't thread.o built with -fasynchronous-unwind-tables?
-fasynchronous-unwind-tables should be on by default with
gcc 4.6.
Comment 14 marcus 2010-11-28 19:53:45 UTC
actually it is built with it and crashes.

Atfer i change thread.o with -fno-asynchronous-unwind-tables
it starts to work again.

so somehting in there confuses the glibc/libgcc unwinder. any clue on how to debug this?
Comment 15 H.J. Lu 2010-11-28 20:38:46 UTC
Which glibc are you using?
Comment 16 marcus 2010-11-28 20:44:38 UTC
glibc-32bit-2.11.2-3.3.1.x86_64

/lib/libc.so.6 
GNU C Library stable release version 2.11.2 (20100531), by Roland McGrath et al.
[...]
Configured for i686-suse-linux.
Compiled by GNU CC version 4.5.0 20100604 [gcc-4_5-branch revision 160292].
Compiled on a Linux 2.6.32 system on 2010-10-27.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        NoVersion patch for broken glibc 2.0 binaries
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
Comment 17 H.J. Lu 2010-11-28 21:05:41 UTC
It sounds like this bug

http://sourceware.org/bugzilla/show_bug.cgi?id=3597

But your glibc should be OK.
Comment 18 austinenglish 2011-06-29 02:16:04 UTC
This bug is now affecting the World of Warcraft launcher, which crashes:
http://bugs.winehq.org/show_bug.cgi?id=27057

I've was able to narrow it down to a single .c file in wine (and a single patch):
http://source.winehq.org/git/wine.git/commitdiff/dc96c688d397eb4ef1392ee6a98f3eb6b176dc56

I'll attach preprocessed files with good/bad gcc.

command used was:
gcc -E -I. -I. -I../../include -I../../include  -D__WINESRC__ -DCOM_NO_WINDOWS_H -D_REENTRANT -fPIC -Wall -pipe -fno-strict-aliasing -Wdeclaration-after-statement -Wempty-body -Wstrict-prototypes -Wtype-limits -Wwrite-strings -Wpointer-arith -Wlogical-op  -g -O2  mutation.c &> ~/output.i

good gcc:
gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3

bad gcc:
gcc (GCC) 4.6.0 20100812 (experimental)
(this is at commit fc00a76a26bb71539e8e4355e824986baf852f32 / Turn on -fomit-frame-pointer by default for 32bit Linux/x86.)
Comment 19 austinenglish 2011-06-29 02:20:27 UTC
Created attachment 24627 [details]
bad preprocessed file
Comment 20 austinenglish 2011-06-29 02:20:42 UTC
Created attachment 24628 [details]
good preproccessed file
Comment 21 Jacek Caban 2011-07-29 18:55:54 UTC
FWIW mutation.c was a Wine bug that is already fixed in Wine.