Made exception_event_request non-blocking, and added
get_exception_status to retrieve the exception result returned by the debugger.
This commit is contained in:
parent
f4d5fefb0a
commit
e939eae00b
|
@ -107,22 +107,39 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
|
||||||
*
|
*
|
||||||
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
|
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
|
||||||
*/
|
*/
|
||||||
static inline int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
|
static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
HANDLE handle = 0;
|
||||||
|
|
||||||
SERVER_START_REQ
|
SERVER_START_REQ
|
||||||
{
|
{
|
||||||
struct exception_event_request *req = server_alloc_req( sizeof(*req),
|
struct queue_exception_event_request *req = server_alloc_req( sizeof(*req),
|
||||||
sizeof(*rec)+sizeof(*context) );
|
sizeof(*rec)+sizeof(*context) );
|
||||||
CONTEXT *context_ptr = server_data_ptr(req);
|
CONTEXT *context_ptr = server_data_ptr(req);
|
||||||
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
|
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
|
||||||
req->first = first_chance;
|
req->first = first_chance;
|
||||||
*rec_ptr = *rec;
|
*rec_ptr = *rec;
|
||||||
*context_ptr = *context;
|
*context_ptr = *context;
|
||||||
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *context = *context_ptr;
|
if (!server_call_noerr( REQ_QUEUE_EXCEPTION_EVENT )) handle = req->handle;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
if (!handle) return 0; /* no debugger present or other error */
|
||||||
|
|
||||||
|
/* No need to wait on the handle since the process gets suspended
|
||||||
|
* once the event is passed to the debugger, so when we get back
|
||||||
|
* here the event has been continued already.
|
||||||
|
*/
|
||||||
|
SERVER_START_REQ
|
||||||
|
{
|
||||||
|
struct get_exception_status_request *req = server_alloc_req( sizeof(*req), sizeof(*context) );
|
||||||
|
req->handle = handle;
|
||||||
|
if (!server_call_noerr( REQ_GET_EXCEPTION_STATUS ))
|
||||||
|
*context = *(CONTEXT *)server_data_ptr(req);
|
||||||
ret = req->status;
|
ret = req->status;
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
NtClose( handle );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -938,13 +938,22 @@ struct wait_debug_event_request
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Send an exception event */
|
/* Queue an exception event */
|
||||||
struct exception_event_request
|
struct queue_exception_event_request
|
||||||
{
|
{
|
||||||
REQUEST_HEADER; /* request header */
|
REQUEST_HEADER; /* request header */
|
||||||
IN int first; /* first chance exception? */
|
IN int first; /* first chance exception? */
|
||||||
OUT int status; /* event continuation status */
|
OUT handle_t handle; /* handle to the queued event */
|
||||||
IN VARARG(record,exc_event); /* thread context followed by exception record */
|
IN VARARG(record,exc_event); /* thread context followed by exception record */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Retrieve the status of an exception event */
|
||||||
|
struct get_exception_status_request
|
||||||
|
{
|
||||||
|
REQUEST_HEADER; /* request header */
|
||||||
|
OUT handle_t handle; /* handle to the queued event */
|
||||||
|
OUT int status; /* event continuation status */
|
||||||
OUT VARARG(context,context); /* modified thread context */
|
OUT VARARG(context,context); /* modified thread context */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1426,7 +1435,8 @@ enum request
|
||||||
REQ_NEXT_THREAD,
|
REQ_NEXT_THREAD,
|
||||||
REQ_NEXT_MODULE,
|
REQ_NEXT_MODULE,
|
||||||
REQ_WAIT_DEBUG_EVENT,
|
REQ_WAIT_DEBUG_EVENT,
|
||||||
REQ_EXCEPTION_EVENT,
|
REQ_QUEUE_EXCEPTION_EVENT,
|
||||||
|
REQ_GET_EXCEPTION_STATUS,
|
||||||
REQ_OUTPUT_DEBUG_STRING,
|
REQ_OUTPUT_DEBUG_STRING,
|
||||||
REQ_CONTINUE_DEBUG_EVENT,
|
REQ_CONTINUE_DEBUG_EVENT,
|
||||||
REQ_DEBUG_PROCESS,
|
REQ_DEBUG_PROCESS,
|
||||||
|
@ -1541,7 +1551,8 @@ union generic_request
|
||||||
struct next_thread_request next_thread;
|
struct next_thread_request next_thread;
|
||||||
struct next_module_request next_module;
|
struct next_module_request next_module;
|
||||||
struct wait_debug_event_request wait_debug_event;
|
struct wait_debug_event_request wait_debug_event;
|
||||||
struct exception_event_request exception_event;
|
struct queue_exception_event_request queue_exception_event;
|
||||||
|
struct get_exception_status_request get_exception_status;
|
||||||
struct output_debug_string_request output_debug_string;
|
struct output_debug_string_request output_debug_string;
|
||||||
struct continue_debug_event_request continue_debug_event;
|
struct continue_debug_event_request continue_debug_event;
|
||||||
struct debug_process_request debug_process;
|
struct debug_process_request debug_process;
|
||||||
|
@ -1581,7 +1592,7 @@ union generic_request
|
||||||
struct async_result_request async_result;
|
struct async_result_request async_result;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 35
|
#define SERVER_PROTOCOL_VERSION 36
|
||||||
|
|
||||||
/* ### make_requests end ### */
|
/* ### make_requests end ### */
|
||||||
/* Everything above this line is generated automatically by tools/make_requests */
|
/* Everything above this line is generated automatically by tools/make_requests */
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct debug_event
|
||||||
enum debug_event_state state; /* event state */
|
enum debug_event_state state; /* event state */
|
||||||
int status; /* continuation status */
|
int status; /* continuation status */
|
||||||
debug_event_t data; /* event data */
|
debug_event_t data; /* event data */
|
||||||
|
CONTEXT context; /* register context */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* debug context */
|
/* debug context */
|
||||||
|
@ -180,10 +181,8 @@ static int fill_unload_dll_event( struct debug_event *event, void *arg )
|
||||||
|
|
||||||
static int fill_output_debug_string_event( struct debug_event *event, void *arg )
|
static int fill_output_debug_string_event( struct debug_event *event, void *arg )
|
||||||
{
|
{
|
||||||
struct output_debug_string_request *req = arg;
|
struct debug_event_output_string *data = arg;
|
||||||
event->data.info.output_string.string = req->string;
|
event->data.info.output_string = *data;
|
||||||
event->data.info.output_string.unicode = req->unicode;
|
|
||||||
event->data.info.output_string.length = req->length;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +216,11 @@ static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link an event at the end of the queue */
|
/* link an event at the end of the queue */
|
||||||
static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event )
|
static void link_event( struct debug_event *event )
|
||||||
{
|
{
|
||||||
|
struct debug_ctx *debug_ctx = event->debugger->debug_ctx;
|
||||||
|
|
||||||
|
assert( debug_ctx );
|
||||||
grab_object( event );
|
grab_object( event );
|
||||||
event->next = NULL;
|
event->next = NULL;
|
||||||
event->prev = debug_ctx->event_tail;
|
event->prev = debug_ctx->event_tail;
|
||||||
|
@ -241,16 +243,6 @@ static struct debug_event *find_event_to_send( struct debug_ctx *debug_ctx )
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build a reply for the send_event request */
|
|
||||||
static void build_exception_event_reply( struct thread *thread, struct object *obj, int signaled )
|
|
||||||
{
|
|
||||||
struct exception_event_request *req = get_req_ptr( thread );
|
|
||||||
struct debug_event *event = (struct debug_event *)obj;
|
|
||||||
assert( obj->ops == &debug_event_ops );
|
|
||||||
req->status = event->status;
|
|
||||||
thread->context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void debug_event_dump( struct object *obj, int verbose )
|
static void debug_event_dump( struct object *obj, int verbose )
|
||||||
{
|
{
|
||||||
struct debug_event *debug_event = (struct debug_event *)obj;
|
struct debug_event *debug_event = (struct debug_event *)obj;
|
||||||
|
@ -297,6 +289,7 @@ static void debug_event_destroy( struct object *obj )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event->sender->context == &event->context) event->sender->context = NULL;
|
||||||
release_object( event->sender );
|
release_object( event->sender );
|
||||||
release_object( event->debugger );
|
release_object( event->debugger );
|
||||||
}
|
}
|
||||||
|
@ -357,15 +350,14 @@ static int continue_debug_event( struct process *process, struct thread *thread,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* queue a debug event for a debugger */
|
/* alloc a debug event for a debugger */
|
||||||
static struct debug_event *queue_debug_event( struct thread *thread, int code, void *arg )
|
static struct debug_event *alloc_debug_event( struct thread *thread, int code,
|
||||||
|
void *arg, CONTEXT *context )
|
||||||
{
|
{
|
||||||
struct thread *debugger = thread->process->debugger;
|
struct thread *debugger = thread->process->debugger;
|
||||||
struct debug_ctx *debug_ctx = debugger->debug_ctx;
|
|
||||||
struct debug_event *event;
|
struct debug_event *event;
|
||||||
|
|
||||||
assert( code > 0 && code <= NB_DEBUG_EVENTS );
|
assert( code > 0 && code <= NB_DEBUG_EVENTS );
|
||||||
assert( debug_ctx );
|
|
||||||
/* cannot queue a debug event for myself */
|
/* cannot queue a debug event for myself */
|
||||||
assert( debugger->process != thread->process );
|
assert( debugger->process != thread->process );
|
||||||
|
|
||||||
|
@ -384,9 +376,11 @@ static struct debug_event *queue_debug_event( struct thread *thread, int code, v
|
||||||
release_object( event );
|
release_object( event );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (context)
|
||||||
link_event( debug_ctx, event );
|
{
|
||||||
suspend_process( thread->process );
|
memcpy( &event->context, context, sizeof(event->context) );
|
||||||
|
thread->context = &event->context;
|
||||||
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,8 +389,13 @@ void generate_debug_event( struct thread *thread, int code, void *arg )
|
||||||
{
|
{
|
||||||
if (thread->process->debugger)
|
if (thread->process->debugger)
|
||||||
{
|
{
|
||||||
struct debug_event *event = queue_debug_event( thread, code, arg );
|
struct debug_event *event = alloc_debug_event( thread, code, arg, NULL );
|
||||||
if (event) release_object( event );
|
if (event)
|
||||||
|
{
|
||||||
|
link_event( event );
|
||||||
|
suspend_process( thread->process );
|
||||||
|
release_object( event );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +534,6 @@ DECL_HANDLER(continue_debug_event)
|
||||||
DECL_HANDLER(debug_process)
|
DECL_HANDLER(debug_process)
|
||||||
{
|
{
|
||||||
struct debug_event_exception data;
|
struct debug_event_exception data;
|
||||||
struct debug_event *event;
|
|
||||||
struct process *process = get_process_from_id( req->pid );
|
struct process *process = get_process_from_id( req->pid );
|
||||||
if (!process) return;
|
if (!process) return;
|
||||||
|
|
||||||
|
@ -550,16 +548,15 @@ DECL_HANDLER(debug_process)
|
||||||
data.record.ExceptionAddress = get_thread_ip( process->thread_list );
|
data.record.ExceptionAddress = get_thread_ip( process->thread_list );
|
||||||
data.record.NumberParameters = 0;
|
data.record.NumberParameters = 0;
|
||||||
data.first = 1;
|
data.first = 1;
|
||||||
if ((event = queue_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data )))
|
generate_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data );
|
||||||
release_object( event );
|
|
||||||
}
|
}
|
||||||
release_object( process );
|
release_object( process );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send an exception event */
|
/* queue an exception event */
|
||||||
DECL_HANDLER(exception_event)
|
DECL_HANDLER(queue_exception_event)
|
||||||
{
|
{
|
||||||
req->status = 0;
|
req->handle = 0;
|
||||||
if (current->process->debugger)
|
if (current->process->debugger)
|
||||||
{
|
{
|
||||||
struct debug_event_exception data;
|
struct debug_event_exception data;
|
||||||
|
@ -574,22 +571,51 @@ DECL_HANDLER(exception_event)
|
||||||
}
|
}
|
||||||
data.record = *rec;
|
data.record = *rec;
|
||||||
data.first = req->first;
|
data.first = req->first;
|
||||||
if ((event = queue_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
|
if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
|
||||||
{
|
{
|
||||||
struct object *obj = &event->obj;
|
if ((req->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE )))
|
||||||
current->context = context;
|
{
|
||||||
sleep_on( 1, &obj, 0, 0, 0, build_exception_event_reply );
|
link_event( event );
|
||||||
|
suspend_process( current->process );
|
||||||
|
}
|
||||||
release_object( event );
|
release_object( event );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* retrieve the status of an exception event */
|
||||||
|
DECL_HANDLER(get_exception_status)
|
||||||
|
{
|
||||||
|
struct debug_event *event;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
req->status = 0;
|
||||||
|
if ((event = (struct debug_event *)get_handle_obj( current->process, req->handle,
|
||||||
|
0, &debug_event_ops )))
|
||||||
|
{
|
||||||
|
if (event->state == EVENT_CONTINUED)
|
||||||
|
{
|
||||||
|
req->status = event->status;
|
||||||
|
if (current->context == &event->context)
|
||||||
|
{
|
||||||
|
size = min( sizeof(CONTEXT), get_req_data_size(req) );
|
||||||
|
memcpy( get_req_data(req), &event->context, size );
|
||||||
|
current->context = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else set_error( STATUS_PENDING );
|
||||||
|
release_object( event );
|
||||||
|
}
|
||||||
|
set_req_data_size( req, size );
|
||||||
|
}
|
||||||
|
|
||||||
/* send an output string to the debugger */
|
/* send an output string to the debugger */
|
||||||
DECL_HANDLER(output_debug_string)
|
DECL_HANDLER(output_debug_string)
|
||||||
{
|
{
|
||||||
if (current->process->debugger)
|
struct debug_event_output_string data;
|
||||||
{
|
|
||||||
struct debug_event *event = queue_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, req );
|
data.string = req->string;
|
||||||
if (event) release_object( event );
|
data.unicode = req->unicode;
|
||||||
}
|
data.length = req->length;
|
||||||
|
generate_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, &data );
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,8 @@ DECL_HANDLER(next_process);
|
||||||
DECL_HANDLER(next_thread);
|
DECL_HANDLER(next_thread);
|
||||||
DECL_HANDLER(next_module);
|
DECL_HANDLER(next_module);
|
||||||
DECL_HANDLER(wait_debug_event);
|
DECL_HANDLER(wait_debug_event);
|
||||||
DECL_HANDLER(exception_event);
|
DECL_HANDLER(queue_exception_event);
|
||||||
|
DECL_HANDLER(get_exception_status);
|
||||||
DECL_HANDLER(output_debug_string);
|
DECL_HANDLER(output_debug_string);
|
||||||
DECL_HANDLER(continue_debug_event);
|
DECL_HANDLER(continue_debug_event);
|
||||||
DECL_HANDLER(debug_process);
|
DECL_HANDLER(debug_process);
|
||||||
|
@ -254,7 +255,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
||||||
(req_handler)req_next_thread,
|
(req_handler)req_next_thread,
|
||||||
(req_handler)req_next_module,
|
(req_handler)req_next_module,
|
||||||
(req_handler)req_wait_debug_event,
|
(req_handler)req_wait_debug_event,
|
||||||
(req_handler)req_exception_event,
|
(req_handler)req_queue_exception_event,
|
||||||
|
(req_handler)req_get_exception_status,
|
||||||
(req_handler)req_output_debug_string,
|
(req_handler)req_output_debug_string,
|
||||||
(req_handler)req_continue_debug_event,
|
(req_handler)req_continue_debug_event,
|
||||||
(req_handler)req_debug_process,
|
(req_handler)req_debug_process,
|
||||||
|
|
|
@ -1066,15 +1066,25 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_request *
|
||||||
cur_pos += dump_varargs_debug_event( req );
|
cur_pos += dump_varargs_debug_event( req );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_exception_event_request( const struct exception_event_request *req )
|
static void dump_queue_exception_event_request( const struct queue_exception_event_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " first=%d,", req->first );
|
fprintf( stderr, " first=%d,", req->first );
|
||||||
fprintf( stderr, " record=" );
|
fprintf( stderr, " record=" );
|
||||||
cur_pos += dump_varargs_exc_event( req );
|
cur_pos += dump_varargs_exc_event( req );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_exception_event_reply( const struct exception_event_request *req )
|
static void dump_queue_exception_event_reply( const struct queue_exception_event_request *req )
|
||||||
{
|
{
|
||||||
|
fprintf( stderr, " handle=%d", req->handle );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_get_exception_status_request( const struct get_exception_status_request *req )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_get_exception_status_reply( const struct get_exception_status_request *req )
|
||||||
|
{
|
||||||
|
fprintf( stderr, " handle=%d,", req->handle );
|
||||||
fprintf( stderr, " status=%d,", req->status );
|
fprintf( stderr, " status=%d,", req->status );
|
||||||
fprintf( stderr, " context=" );
|
fprintf( stderr, " context=" );
|
||||||
cur_pos += dump_varargs_context( req );
|
cur_pos += dump_varargs_context( req );
|
||||||
|
@ -1548,7 +1558,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_next_thread_request,
|
(dump_func)dump_next_thread_request,
|
||||||
(dump_func)dump_next_module_request,
|
(dump_func)dump_next_module_request,
|
||||||
(dump_func)dump_wait_debug_event_request,
|
(dump_func)dump_wait_debug_event_request,
|
||||||
(dump_func)dump_exception_event_request,
|
(dump_func)dump_queue_exception_event_request,
|
||||||
|
(dump_func)dump_get_exception_status_request,
|
||||||
(dump_func)dump_output_debug_string_request,
|
(dump_func)dump_output_debug_string_request,
|
||||||
(dump_func)dump_continue_debug_event_request,
|
(dump_func)dump_continue_debug_event_request,
|
||||||
(dump_func)dump_debug_process_request,
|
(dump_func)dump_debug_process_request,
|
||||||
|
@ -1659,7 +1670,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||||
(dump_func)dump_next_thread_reply,
|
(dump_func)dump_next_thread_reply,
|
||||||
(dump_func)dump_next_module_reply,
|
(dump_func)dump_next_module_reply,
|
||||||
(dump_func)dump_wait_debug_event_reply,
|
(dump_func)dump_wait_debug_event_reply,
|
||||||
(dump_func)dump_exception_event_reply,
|
(dump_func)dump_queue_exception_event_reply,
|
||||||
|
(dump_func)dump_get_exception_status_reply,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
@ -1770,7 +1782,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||||
"next_thread",
|
"next_thread",
|
||||||
"next_module",
|
"next_module",
|
||||||
"wait_debug_event",
|
"wait_debug_event",
|
||||||
"exception_event",
|
"queue_exception_event",
|
||||||
|
"get_exception_status",
|
||||||
"output_debug_string",
|
"output_debug_string",
|
||||||
"continue_debug_event",
|
"continue_debug_event",
|
||||||
"debug_process",
|
"debug_process",
|
||||||
|
|
|
@ -138,6 +138,48 @@ static void format_exception_msg( const EXCEPTION_POINTERS *ptr, char *buffer )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************
|
||||||
|
* send_debug_event
|
||||||
|
*
|
||||||
|
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
|
||||||
|
*/
|
||||||
|
static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *context )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
HANDLE handle = 0;
|
||||||
|
|
||||||
|
SERVER_START_REQ
|
||||||
|
{
|
||||||
|
struct queue_exception_event_request *req = server_alloc_req( sizeof(*req),
|
||||||
|
sizeof(*rec)+sizeof(*context) );
|
||||||
|
CONTEXT *context_ptr = server_data_ptr(req);
|
||||||
|
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
|
||||||
|
req->first = first_chance;
|
||||||
|
*rec_ptr = *rec;
|
||||||
|
*context_ptr = *context;
|
||||||
|
if (!server_call_noerr( REQ_QUEUE_EXCEPTION_EVENT )) handle = req->handle;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
if (!handle) return 0; /* no debugger present or other error */
|
||||||
|
|
||||||
|
/* No need to wait on the handle since the process gets suspended
|
||||||
|
* once the event is passed to the debugger, so when we get back
|
||||||
|
* here the event has been continued already.
|
||||||
|
*/
|
||||||
|
SERVER_START_REQ
|
||||||
|
{
|
||||||
|
struct get_exception_status_request *req = server_alloc_req( sizeof(*req), sizeof(*context) );
|
||||||
|
req->handle = handle;
|
||||||
|
if (!server_call_noerr( REQ_GET_EXCEPTION_STATUS ))
|
||||||
|
*context = *(CONTEXT *)server_data_ptr(req);
|
||||||
|
ret = req->status;
|
||||||
|
}
|
||||||
|
SERVER_END_REQ;
|
||||||
|
NtClose( handle );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* UnhandledExceptionFilter (KERNEL32.537)
|
* UnhandledExceptionFilter (KERNEL32.537)
|
||||||
*/
|
*/
|
||||||
|
@ -151,20 +193,7 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
/* send a last chance event to the debugger */
|
/* send a last chance event to the debugger */
|
||||||
SERVER_START_REQ
|
status = send_debug_event( epointers->ExceptionRecord, FALSE, epointers->ContextRecord );
|
||||||
{
|
|
||||||
struct exception_event_request *req = server_alloc_req( sizeof(*req),
|
|
||||||
sizeof(EXCEPTION_RECORD)+sizeof(CONTEXT) );
|
|
||||||
CONTEXT *context_ptr = server_data_ptr(req);
|
|
||||||
EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1);
|
|
||||||
req->first = 0;
|
|
||||||
*rec_ptr = *epointers->ExceptionRecord;
|
|
||||||
*context_ptr = *epointers->ContextRecord;
|
|
||||||
if (!server_call_noerr( REQ_EXCEPTION_EVENT )) *epointers->ContextRecord = *context_ptr;
|
|
||||||
status = req->status;
|
|
||||||
}
|
|
||||||
SERVER_END_REQ;
|
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case DBG_CONTINUE:
|
case DBG_CONTINUE:
|
||||||
|
|
Loading…
Reference in New Issue