Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e939eae0
Commit
e939eae0
authored
Jan 26, 2001
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Made exception_event_request non-blocking, and added
get_exception_status to retrieve the exception result returned by the debugger.
parent
f4d5fefb
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
168 additions
and
70 deletions
+168
-70
exception.c
dlls/ntdll/exception.c
+21
-4
server.h
include/server.h
+17
-6
debugger.c
server/debugger.c
+65
-39
request.h
server/request.h
+4
-2
trace.c
server/trace.c
+18
-5
except.c
win32/except.c
+43
-14
No files found.
dlls/ntdll/exception.c
View file @
e939eae0
...
...
@@ -107,22 +107,39 @@ static DWORD EXC_CallHandler( EXCEPTION_RECORD *record, EXCEPTION_FRAME *frame,
*
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
*/
static
in
line
in
t
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
;
HANDLE
handle
=
0
;
SERVER_START_REQ
{
struct
exception_event_request
*
req
=
server_alloc_req
(
sizeof
(
*
req
),
sizeof
(
*
rec
)
+
sizeof
(
*
context
)
);
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_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
;
}
SERVER_END_REQ
;
NtClose
(
handle
);
return
ret
;
}
...
...
include/server.h
View file @
e939eae0
...
...
@@ -938,13 +938,22 @@ struct wait_debug_event_request
};
/*
Send
an exception event */
struct
exception_event_request
/*
Queue
an exception event */
struct
queue_
exception_event_request
{
REQUEST_HEADER
;
/* request header */
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 */
};
/* 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 */
};
...
...
@@ -1426,7 +1435,8 @@ enum request
REQ_NEXT_THREAD
,
REQ_NEXT_MODULE
,
REQ_WAIT_DEBUG_EVENT
,
REQ_EXCEPTION_EVENT
,
REQ_QUEUE_EXCEPTION_EVENT
,
REQ_GET_EXCEPTION_STATUS
,
REQ_OUTPUT_DEBUG_STRING
,
REQ_CONTINUE_DEBUG_EVENT
,
REQ_DEBUG_PROCESS
,
...
...
@@ -1541,7 +1551,8 @@ union generic_request
struct
next_thread_request
next_thread
;
struct
next_module_request
next_module
;
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
continue_debug_event_request
continue_debug_event
;
struct
debug_process_request
debug_process
;
...
...
@@ -1581,7 +1592,7 @@ union generic_request
struct
async_result_request
async_result
;
};
#define SERVER_PROTOCOL_VERSION 3
5
#define SERVER_PROTOCOL_VERSION 3
6
/* ### make_requests end ### */
/* Everything above this line is generated automatically by tools/make_requests */
...
...
server/debugger.c
View file @
e939eae0
...
...
@@ -28,6 +28,7 @@ struct debug_event
enum
debug_event_state
state
;
/* event state */
int
status
;
/* continuation status */
debug_event_t
data
;
/* event data */
CONTEXT
context
;
/* register 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
)
{
struct
output_debug_string_request
*
req
=
arg
;
event
->
data
.
info
.
output_string
.
string
=
req
->
string
;
event
->
data
.
info
.
output_string
.
unicode
=
req
->
unicode
;
event
->
data
.
info
.
output_string
.
length
=
req
->
length
;
struct
debug_event_output_string
*
data
=
arg
;
event
->
data
.
info
.
output_string
=
*
data
;
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 */
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
);
event
->
next
=
NULL
;
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
;
}
/* 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
)
{
struct
debug_event
*
debug_event
=
(
struct
debug_event
*
)
obj
;
...
...
@@ -297,6 +289,7 @@ static void debug_event_destroy( struct object *obj )
break
;
}
}
if
(
event
->
sender
->
context
==
&
event
->
context
)
event
->
sender
->
context
=
NULL
;
release_object
(
event
->
sender
);
release_object
(
event
->
debugger
);
}
...
...
@@ -357,15 +350,14 @@ static int continue_debug_event( struct process *process, struct thread *thread,
return
0
;
}
/* queue a debug event for a debugger */
static
struct
debug_event
*
queue_debug_event
(
struct
thread
*
thread
,
int
code
,
void
*
arg
)
/* alloc a debug event for a debugger */
static
struct
debug_event
*
alloc_debug_event
(
struct
thread
*
thread
,
int
code
,
void
*
arg
,
CONTEXT
*
context
)
{
struct
thread
*
debugger
=
thread
->
process
->
debugger
;
struct
debug_ctx
*
debug_ctx
=
debugger
->
debug_ctx
;
struct
debug_event
*
event
;
assert
(
code
>
0
&&
code
<=
NB_DEBUG_EVENTS
);
assert
(
debug_ctx
);
/* cannot queue a debug event for myself */
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
);
return
NULL
;
}
link_event
(
debug_ctx
,
event
);
suspend_process
(
thread
->
process
);
if
(
context
)
{
memcpy
(
&
event
->
context
,
context
,
sizeof
(
event
->
context
)
);
thread
->
context
=
&
event
->
context
;
}
return
event
;
}
...
...
@@ -395,8 +389,13 @@ void generate_debug_event( struct thread *thread, int code, void *arg )
{
if
(
thread
->
process
->
debugger
)
{
struct
debug_event
*
event
=
queue_debug_event
(
thread
,
code
,
arg
);
if
(
event
)
release_object
(
event
);
struct
debug_event
*
event
=
alloc_debug_event
(
thread
,
code
,
arg
,
NULL
);
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
)
{
struct
debug_event_exception
data
;
struct
debug_event
*
event
;
struct
process
*
process
=
get_process_from_id
(
req
->
pid
);
if
(
!
process
)
return
;
...
...
@@ -550,16 +548,15 @@ DECL_HANDLER(debug_process)
data
.
record
.
ExceptionAddress
=
get_thread_ip
(
process
->
thread_list
);
data
.
record
.
NumberParameters
=
0
;
data
.
first
=
1
;
if
((
event
=
queue_debug_event
(
process
->
thread_list
,
EXCEPTION_DEBUG_EVENT
,
&
data
)))
release_object
(
event
);
generate_debug_event
(
process
->
thread_list
,
EXCEPTION_DEBUG_EVENT
,
&
data
);
}
release_object
(
process
);
}
/*
send
an exception event */
DECL_HANDLER
(
exception_event
)
/*
queue
an exception event */
DECL_HANDLER
(
queue_
exception_event
)
{
req
->
status
=
0
;
req
->
handle
=
0
;
if
(
current
->
process
->
debugger
)
{
struct
debug_event_exception
data
;
...
...
@@ -574,22 +571,51 @@ DECL_HANDLER(exception_event)
}
data
.
record
=
*
rec
;
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
;
current
->
context
=
context
;
sleep_on
(
1
,
&
obj
,
0
,
0
,
0
,
build_exception_event_reply
);
if
((
req
->
handle
=
alloc_handle
(
current
->
process
,
event
,
SYNCHRONIZE
,
FALSE
)))
{
link_event
(
event
);
suspend_process
(
current
->
process
);
}
release_object
(
event
);
}
}
}
/*
send an output string to the debugger
*/
DECL_HANDLER
(
output_debug_string
)
/*
retrieve the status of an exception event
*/
DECL_HANDLER
(
get_exception_status
)
{
if
(
current
->
process
->
debugger
)
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
)))
{
struct
debug_event
*
event
=
queue_debug_event
(
current
,
OUTPUT_DEBUG_STRING_EVENT
,
req
);
if
(
event
)
release_object
(
event
);
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 */
DECL_HANDLER
(
output_debug_string
)
{
struct
debug_event_output_string
data
;
data
.
string
=
req
->
string
;
data
.
unicode
=
req
->
unicode
;
data
.
length
=
req
->
length
;
generate_debug_event
(
current
,
OUTPUT_DEBUG_STRING_EVENT
,
&
data
);
}
server/request.h
View file @
e939eae0
...
...
@@ -140,7 +140,8 @@ DECL_HANDLER(next_process);
DECL_HANDLER
(
next_thread
);
DECL_HANDLER
(
next_module
);
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
(
continue_debug_event
);
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_module
,
(
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_continue_debug_event
,
(
req_handler
)
req_debug_process
,
...
...
server/trace.c
View file @
e939eae0
...
...
@@ -1066,15 +1066,25 @@ static void dump_wait_debug_event_reply( const struct wait_debug_event_request *
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
,
" record="
);
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
,
" context="
);
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_module_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_continue_debug_event_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_module_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
,
...
...
@@ -1770,7 +1782,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"next_thread"
,
"next_module"
,
"wait_debug_event"
,
"exception_event"
,
"queue_exception_event"
,
"get_exception_status"
,
"output_debug_string"
,
"continue_debug_event"
,
"debug_process"
,
...
...
win32/except.c
View file @
e939eae0
...
...
@@ -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)
*/
...
...
@@ -151,20 +193,7 @@ DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
int
status
;
/* send a last chance event to the debugger */
SERVER_START_REQ
{
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
;
status
=
send_debug_event
(
epointers
->
ExceptionRecord
,
FALSE
,
epointers
->
ContextRecord
);
switch
(
status
)
{
case
DBG_CONTINUE
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment