[PATCH] kernel32: make it possible to create a backtrace from a RaiseException exception in gdb
bernhardloos at googlemail.com
Tue Sep 27 10:47:25 CDT 2011
On Tue, Sep 27, 2011 at 4:34 PM, Alexandre Julliard <julliard at winehq.org> wrote:
> Bernhard Loos <bernhardloos at 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;
>> + "mov 0x4(%esp),%eax\n\t"
>> + "push %eax\n\t"
>> + "mov 0xc(%esp),%eax\n\t"
>> + "call *%eax\n\t"
>> + "ret")
> 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 at winehq.org
More information about the wine-devel