Re: Frame-based exception handling problem on Server 2008
- From: Corinna Vinschen <corinna@xxxxxxxxxxxxxxxx>
- Date: Sat, 23 Feb 2008 21:00:17 +0000 (UTC)
Corinna Vinschen wrote:
Ivan Brugiolo [MSFT] wrote:
[...]
To debug debug the issue, start from KeUserExceptionDispatcher.
That's the first function you can set a breakpoint on in user mode.
Then, with good symbols, observer the code that walks the frame-handler
list,
and, check if some Rtl*Validate* function is called.
The example code I sent in my reply to Jeffrey (message-id:
<fpmnif$7i4$1@xxxxxxxxxxxxxxx>) is a self-contained testcase.
[...]
I'm not fluent in debugging the OS DLLs. I can surely look into this
after I have set up and learned how to use windbg.
Ok, I bit the bullet, installed WinDbg, Visual-C++ and the debug symbols
for 2008. I changed the example code to compile under Visual-C++ and
debugged according to your above instructions. The call stack when it's
in the endless loop looks like this:
ntdll!RtlDispatchException+0x67
ntdll!KiUserExceptionDispatcher+0xf
exceptionhandler_example!func+0x22
exceptionhandler_example!main+0x6c
exceptionhandler_example!__tmainCRTStartup+0x1a8
exceptionhandler_example!mainCRTStartup+0xf
kernel32!BaseThreadInitThunk+0xe
ntdll!__RtlUserThreadStart+0x23
ntdll!_RtlUserThreadStart+0x1b
When stepping from KiUserExceptionDispatcher to RtlDispatchException,
there is no call to any Rtl*Validate* function, nor is there a call to
RtlIsValidHandler (which is one function which looks like a likely
candidate). The endless loop occurs as soon as the PC is at
ntdll!RtlDispatchException+0x67.
This is the full assembler code of the entire loop:
ntdll!RtlDispatchException+0x67:
76e80d6d 3b5df8 cmp ebx,dword ptr [ebp-8]
76e80d70 0f829ad1feff jb ntdll!RtlDispatchException+0x19d (76e6df10)
76e80d76 8d4308 lea eax,[ebx+8]
76e80d79 3b45f4 cmp eax,dword ptr [ebp-0Ch]
76e80d7c 0f878ed1feff ja ntdll!RtlDispatchException+0x19d (76e6df10)
76e80d82 f6c303 test bl,3
76e80d85 0f8585d1feff jne ntdll!RtlDispatchException+0x19d (76e6df10)
76e80d8b 8b4304 mov eax,dword ptr [ebx+4]
76e80d8e 3b45f8 cmp eax,dword ptr [ebp-8]
76e80d91 7209 jb ntdll!RtlDispatchException+0x96 (76e80d9c)
76e80d93 3b45f4 cmp eax,dword ptr [ebp-0Ch]
76e80d96 0f8274d1feff jb ntdll!RtlDispatchException+0x19d (76e6df10)
76e80d9c 8b1b mov ebx,dword ptr [ebx]
76e80d9e 3bdf cmp ebx,edi
76e80da0 75cb jne ntdll!RtlDispatchException+0x67 (76e80d6d) [br=1]
That's it. It stays in this loop until the process is stopped. Is that
enough for you to debug this further? I don't know what it's doing in
this loop, sorry.
Below is the code of the example applications changed so that it can be
build with VC++:
=================== SNIP ===================
#include <stdio.h>
#include <windows.h>
//#ifdef __GNUC__
extern DWORD __stdcall RtlUnwind (void *, void *, EXCEPTION_RECORD *, void *);
//#endif
struct _exception_list;
typedef int (*exception_handler_t) (EXCEPTION_RECORD *,
struct _exception_list *,
CONTEXT *,
void *);
typedef struct _exception_list
{
struct _exception_list *prev;
exception_handler_t handler;
} exception_list_t;
typedef struct _cygtls
{
exception_list_t el;
} cygtls_t;
#ifdef __GNUC__
extern exception_list_t *_except_list __asm__ ("%fs:0");
#endif
void
init_exception_handler (cygtls_t *tls, exception_handler_t eh, int do_loop)
{
exception_list_t *_except_list;
tls->el.handler = eh;
if (do_loop)
tls->el.prev = &tls->el; // loop back to itself
else
#ifdef __GNUC__
tls->el.prev = _except_list; // Just point to default handler
_except_list = &tls->el;
#else
{
__asm { mov eax, fs:[0]
mov _except_list, eax }
tls->el.prev = _except_list;
}
_except_list = &tls->el;
__asm { mov eax, _except_list
mov fs:[0], eax }
#endif
}
int
handle_exception (EXCEPTION_RECORD *e, exception_list_t *frame,
CONTEXT *c, void *dummy)
{
fputs ("In exception_handler\n", stderr);
RtlUnwind (frame, (void *) c->Eip, e, 0);
return 0;
}
int
func (int a, int b)
{
return a / b;
}
int
main (int argc, char **argv)
{
cygtls_t _my_tls;
init_exception_handler (&_my_tls, handle_exception, argc <= 1);
fputs ("Before func\n", stderr);
func (1, 0);
fputs ("After func\n", stderr);
return 0;
}
=================== SNAP ===================
Corinna
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat
.
- Follow-Ups:
- Re: Frame-based exception handling problem on Server 2008
- From: Ivan Brugiolo [MSFT]
- Re: Frame-based exception handling problem on Server 2008
- References:
- Frame-based exception handling problem on Server 2008
- From: Corinna Vinschen
- RE: Frame-based exception handling problem on Server 2008
- From: "Jeffrey Tan[MSFT]"
- Re: Frame-based exception handling problem on Server 2008
- From: Corinna Vinschen
- Re: Frame-based exception handling problem on Server 2008
- From: Ivan Brugiolo [MSFT]
- Re: Frame-based exception handling problem on Server 2008
- From: Corinna Vinschen
- Re: Frame-based exception handling problem on Server 2008
- From: Ivan Brugiolo [MSFT]
- Re: Frame-based exception handling problem on Server 2008
- From: Corinna Vinschen
- Frame-based exception handling problem on Server 2008
- Prev by Date: Re: high resolution timers
- Next by Date: Re: Problem about write to named pipe.
- Previous by thread: Re: Frame-based exception handling problem on Server 2008
- Next by thread: Re: Frame-based exception handling problem on Server 2008
- Index(es):
Relevant Pages
|