http://bugs.winehq.org/show_bug.cgi?id=34254
Bug #: 34254 Summary: Wine64 seh:RtlUnwindEx error with c++ exception handling Product: Wine Version: unspecified Platform: x86-64 OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: kernel32 AssignedTo: wine-bugs@winehq.org ReportedBy: alejandropuchades@gmx.com Classification: Unclassified
Description of problem: When I was implementing a C wrapper for a C++ library, catching all possible exceptions in C++-land, I noticed my exception handlers were not being called and my app crashed under wine64. The same binary run just fine under windows 7, so it had to be a wine bug. Also, the same code compiled for 32 bits run successfully under the 32 bits version of wine.
System information: Fedora 19 x86_64, binaries compiled with the 32 and 64 bits versions of MinGW
Version-Release number of selected component (if applicable): $ wine64 --version wine-1.6
How reproducible: (assuming current-dir = uncompressed attachment)
Steps to Reproduce: 1. $ ./compile64.sh 2. $ wine64 ./main.exe
Actual results: throwing exception err:seh:RtlUnwindEx invalid frame 7fff42757fd0 (0x132000-0x330000) err:seh:setup_exception stack overflow 2416 bytes in thread 0009 eip 0007fb39b2ab22b esp 0000000000130c90 stack 0x130000-0x131000-0x330000
Expected results: No crash :) Just what happens when compiled with compile32.sh: throwing exception exception caught
Additional info: Source code triggering the bug attached below.
http://bugs.winehq.org/show_bug.cgi?id=34254
--- Comment #1 from Alex Puchades alejandropuchades@gmx.com 2013-08-12 11:53:41 CDT --- Created attachment 45587 --> http://bugs.winehq.org/attachment.cgi?id=45587 The offending code
http://bugs.winehq.org/show_bug.cgi?id=34254
Alex Puchades alejandropuchades@gmx.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Version|unspecified |1.6
http://bugs.winehq.org/show_bug.cgi?id=34254
Alex Puchades alejandropuchades@gmx.com changed:
What |Removed |Added ---------------------------------------------------------------------------- See Also| |https://bugzilla.redhat.com | |/show_bug.cgi?id=996203
http://bugs.winehq.org/show_bug.cgi?id=34254
Alex Puchades alejandropuchades@gmx.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |alejandropuchades@gmx.com
http://bugs.winehq.org/show_bug.cgi?id=34254
Austin English austinenglish@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download, testcase, win64
http://bugs.winehq.org/show_bug.cgi?id=34254
André H. nerv@dawncrow.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |nerv@dawncrow.de
http://bugs.winehq.org/show_bug.cgi?id=34254
--- Comment #2 from Alex Puchades alex94puchades@autistici.org 2013-12-10 16:15:35 CST --- URL to compressed "trace-all" output (showed errs at lines 89137 and 8378015):
https://dl.dropboxusercontent.com/u/47594913/log.txt.xz
Seems that the error is in RtlUnwindEx, inside dlls/ntdll/signal_x86_64.c, err trace at line 3041
https://bugs.winehq.org/show_bug.cgi?id=34254
Tavian Barnes tavianator@tavianator.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |tavianator@tavianator.com
https://bugs.winehq.org/show_bug.cgi?id=34254
Sebastian Lackner sebastian@fds-team.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |sebastian@fds-team.de
https://bugs.winehq.org/show_bug.cgi?id=34254
--- Comment #3 from Sebastian Lackner sebastian@fds-team.de --- I am wondering a bit why noone looked at this bug yet, especially because its so easy to reproduce. For those trying to reproduce, if wine complains about missing dlls, just compile the DLL -static.
The issue still exists in wine-1.7.35.
Relevant output from +seh,+tid,+relay:
--- snip --- 0036:Call KERNEL32.RaiseException(20474343,00000000,00000001,0033fa00) ret=6becf3b7 0036:trace:seh:raise_exception code=20474343 flags=0 addr=0x7b84b750 ip=7b84b750 tid=0036 0036:trace:seh:raise_exception info[0]=00000000004332f0 [...] 0036:trace:seh:call_handler calling handler 0x6bf303f0 (rec=0x33f7f0, frame=0x33fba0 context=0x33eaa0, dispatch=0x33ef70) 0036:Call ntdll.RtlUnwindEx(0033fba0,6bec14de,0033f7f0,004332f0,0033eaa0,0033efc0) ret=6becf331 0036:trace:seh:RtlUnwindEx code=20474343 flags=2 end_frame=0x33fba0 target_ip=0x6bec14de rip=00007f843f4e9c14 0036:trace:seh:RtlUnwindEx info[0]=00000000004332f0 0036:trace:seh:RtlUnwindEx info[1]=000000000033fba0 0036:trace:seh:RtlUnwindEx info[2]=000000006bec14de 0036:trace:seh:RtlUnwindEx info[3]=0000000000000001 [...] 0036:trace:seh:call_unwind_handler calling handler 0x6bf303f0 (rec=0x33f7f0, frame=0x33fba0 context=0x33eaa0, dispatch=0x33e0d0) 0036:trace:seh:call_unwind_handler handler 0x6bf303f0 returned 1 0036:trace:seh:RtlVirtualUnwind type 2 rip 401546 rsp 33fbc0 --- snip ---
The first RaiseException is the initial exception which is thrown by the application. The handler which is called afterwards internally calls "RtlUnwindEx" to resume execution at the desired frame and target ip. Unfortunately the function unwinds a bit too much, until it reaches the end of the stack. Rsp never matches exactly the target frame, so the function never stops.
Please note that nested exception handling / unwind is still missing completely on x86_64, but not sure if that is related to the problem described here. I think the unwinding should work even without nested exception handling support.
Hacky workaround:
--- snip --- diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 05581c2..0001cc0 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -3164,6 +3164,7 @@ void WINAPI RtlUnwindEx( PVOID end_frame, PVOID target_ip, EXCEPTION_RECORD *rec } if (dispatch.EstablisherFrame == (ULONG64)end_frame) rec->ExceptionFlags |= EH_TARGET_UNWIND; call_unwind_handler( rec, &dispatch ); + if (dispatch.EstablisherFrame == (ULONG64)end_frame) break; } else /* hack: call builtin handlers registered in the tib list */ { --- snip ---
With that changed the target application works as desired, but I am not sure if this change is correct. If someone more familiar with this area would take a look, that would be very appreciated.
https://bugs.winehq.org/show_bug.cgi?id=34254
--- Comment #4 from Sebastian Lackner sebastian@fds-team.de --- Created attachment 50569 --> https://bugs.winehq.org/attachment.cgi?id=50569 ntdll: Fix check for end_frame in RtlUnwindEx on x86_64.
After reading a couple more websites and documentations I think that the check "if (context->Rsp == (ULONG64)end_frame) break;" most likely never worked correctly. The attached patch is probably a bit more correct than the hack above.
https://bugs.winehq.org/show_bug.cgi?id=34254
Sebastian Lackner sebastian@fds-team.de changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |julliard@winehq.org
--- Comment #5 from Sebastian Lackner sebastian@fds-team.de --- As it turns out this issue is technically a regression. My patch in comment #4 is exactly the opposite of a change which was committed a couple of years ago:
--- snip --- commit a777676bc48d4575a0bafb40bad1fe85d269e352 Author: Alexandre Julliard julliard@winehq.org Date: Fri Mar 30 14:42:55 2012 +0200
ntdll: Also call the unwind handler for the target frame. --- snip ---
Unfortunately I wasn't able to find out why this change was introduced. It seems to violate all available documentations that further unwind handlers are called after the first one with EH_TARGET_UNWIND. I assume that the idea was to run one more round of unwind handlers (why?), but this can't work because there is no relation between Rsp and EstablisherFrames. Rsp points to the location after the return address was removed, but EstablisherFrame is smaller and points to the location of the local variables / saved registers.
Adding Alexandre as CC, maybe he remembers why this change was necessary.
https://bugs.winehq.org/show_bug.cgi?id=34254
Béla Gyebrószki gyebro69@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |regression CC| |gyebro69@gmail.com Regression SHA1| |a777676bc48d4575a0bafb40bad | |1fe85d269e352
https://bugs.winehq.org/show_bug.cgi?id=34254
Sebastian Lackner sebastian@fds-team.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |patch
--- Comment #6 from Sebastian Lackner sebastian@fds-team.de --- The following patch should be a more complete fix: https://github.com/wine-compholio/wine-staging/blob/master/patches/ntdll-Rtl...
https://bugs.winehq.org/show_bug.cgi?id=34254
Sebastian Lackner sebastian@fds-team.de changed:
What |Removed |Added ---------------------------------------------------------------------------- Fixed by SHA1| |33c3990e4d5f637807eee55367b | |9f49f761571ef Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED
--- Comment #7 from Sebastian Lackner sebastian@fds-team.de --- Fixed with 33c3990e4d5f637807eee55367b9f49f761571ef.
https://bugs.winehq.org/show_bug.cgi?id=34254
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #8 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 1.7.40.
https://bugs.winehq.org/show_bug.cgi?id=34254
Saulius K. saulius2@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |saulius2@gmail.com