ntdll: Don't call vectored exception handlers under the critical section.
This commit is contained in:
parent
177a7e5683
commit
11e71ede14
|
@ -44,6 +44,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
PVECTORED_EXCEPTION_HANDLER func;
|
PVECTORED_EXCEPTION_HANDLER func;
|
||||||
|
ULONG count;
|
||||||
} VECTORED_HANDLER;
|
} VECTORED_HANDLER;
|
||||||
|
|
||||||
static struct list vectored_handlers = LIST_INIT(vectored_handlers);
|
static struct list vectored_handlers = LIST_INIT(vectored_handlers);
|
||||||
|
@ -158,21 +159,37 @@ LONG call_vectored_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
|
||||||
struct list *ptr;
|
struct list *ptr;
|
||||||
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
||||||
EXCEPTION_POINTERS except_ptrs;
|
EXCEPTION_POINTERS except_ptrs;
|
||||||
|
VECTORED_HANDLER *handler, *to_free = NULL;
|
||||||
|
|
||||||
except_ptrs.ExceptionRecord = rec;
|
except_ptrs.ExceptionRecord = rec;
|
||||||
except_ptrs.ContextRecord = context;
|
except_ptrs.ContextRecord = context;
|
||||||
|
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
LIST_FOR_EACH( ptr, &vectored_handlers )
|
ptr = list_head( &vectored_handlers );
|
||||||
|
while (ptr)
|
||||||
{
|
{
|
||||||
VECTORED_HANDLER *handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
||||||
|
handler->count++;
|
||||||
|
RtlLeaveCriticalSection( &vectored_handlers_section );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, to_free );
|
||||||
|
to_free = NULL;
|
||||||
|
|
||||||
TRACE( "calling handler at %p code=%x flags=%x\n",
|
TRACE( "calling handler at %p code=%x flags=%x\n",
|
||||||
handler->func, rec->ExceptionCode, rec->ExceptionFlags );
|
handler->func, rec->ExceptionCode, rec->ExceptionFlags );
|
||||||
ret = handler->func( &except_ptrs );
|
ret = handler->func( &except_ptrs );
|
||||||
TRACE( "handler at %p returned %x\n", handler->func, ret );
|
TRACE( "handler at %p returned %x\n", handler->func, ret );
|
||||||
|
|
||||||
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
|
ptr = list_next( &vectored_handlers, ptr );
|
||||||
|
if (!--handler->count) /* removed during execution */
|
||||||
|
{
|
||||||
|
list_remove( &handler->entry );
|
||||||
|
to_free = handler;
|
||||||
|
}
|
||||||
if (ret == EXCEPTION_CONTINUE_EXECUTION) break;
|
if (ret == EXCEPTION_CONTINUE_EXECUTION) break;
|
||||||
}
|
}
|
||||||
RtlLeaveCriticalSection( &vectored_handlers_section );
|
RtlLeaveCriticalSection( &vectored_handlers_section );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, to_free );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +231,7 @@ PVOID WINAPI RtlAddVectoredExceptionHandler( ULONG first, PVECTORED_EXCEPTION_HA
|
||||||
if (handler)
|
if (handler)
|
||||||
{
|
{
|
||||||
handler->func = func;
|
handler->func = func;
|
||||||
|
handler->count = 1;
|
||||||
RtlEnterCriticalSection( &vectored_handlers_section );
|
RtlEnterCriticalSection( &vectored_handlers_section );
|
||||||
if (first) list_add_head( &vectored_handlers, &handler->entry );
|
if (first) list_add_head( &vectored_handlers, &handler->entry );
|
||||||
else list_add_tail( &vectored_handlers, &handler->entry );
|
else list_add_tail( &vectored_handlers, &handler->entry );
|
||||||
|
@ -237,7 +255,8 @@ ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
|
||||||
VECTORED_HANDLER *curr_handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
VECTORED_HANDLER *curr_handler = LIST_ENTRY( ptr, VECTORED_HANDLER, entry );
|
||||||
if (curr_handler == handler)
|
if (curr_handler == handler)
|
||||||
{
|
{
|
||||||
list_remove( ptr );
|
if (!--curr_handler->count) list_remove( ptr );
|
||||||
|
else handler = NULL; /* don't free it yet */
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue