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.