On Tue, Sep 27, 2011 at 4:34 PM, Alexandre Julliard julliard@winehq.org wrote:
Bernhard Loos bernhardloos@googlemail.com writes:
@@ -60,6 +60,17 @@ static PTOP_LEVEL_EXCEPTION_FILTER top_filter; typedef INT (WINAPI *MessageBoxA_funcptr)(HWND,LPCSTR,LPCSTR,UINT); typedef INT (WINAPI *MessageBoxW_funcptr)(HWND,LPCWSTR,LPCWSTR,UINT);
+#ifdef __i386__ +/* without this, it's impossible to get a backtrace from the raised
- exception in winedbg in gdb mode */
+void RaiseException_helper(EXCEPTION_RECORD *r, void *f) DECLSPEC_HIDDEN; +__ASM_GLOBAL_FUNC(RaiseException_helper,
- "mov 0x4(%esp),%eax\n\t"
- "push %eax\n\t"
- "mov 0xc(%esp),%eax\n\t"
- "call *%eax\n\t"
- "ret")
+#endif
You shouldn't need anything like that.
I don't think it's really possible to avoid this. The problem goes like that: gcc adjusts esp once at the function start and then never touches it again until the function returns. This works quite well, if only __cdecl functions are called, but as __stdcall functions clean up their stack, gcc produces something like this:
0x7b839cf1 <+81>: mov %eax,(%esp) 0x7b839cf4 <+84>: call 0x7b839c90 <RtlRaiseException_helper2> 0x7b839cf9 <+89>: sub $0x4,%esp 0x7b839cfc <+92>: add $0x64,%esp 0x7b839cff <+95>: pop %ebx 0x7b839d00 <+96>: pop %esi 0x7b839d01 <+97>: ret $0x10
RtlRaiseException_helper2 has one argument in this case and gcc retores the original esp value after the call. The problem is, that gcc doesn't emit DWARF frame adjustment ops for this whole exercise, so for the single instruction at 0x7b839cf9, gdb assumes the wrong Esp value and the result are broken backtraces. Usually, this doesn't hurt much but in this case the Eip value for the exception context points there which makes this pretty annoying.
-- Alexandre Julliard julliard@winehq.org