Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
17cf8101
Commit
17cf8101
authored
Nov 24, 1999
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed handling of debug events on thread/process exit.
parent
6f1b6424
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
42 additions
and
39 deletions
+42
-39
debugger.c
server/debugger.c
+24
-33
process.c
server/process.c
+15
-2
process.h
server/process.h
+1
-2
thread.c
server/thread.c
+1
-1
thread.h
server/thread.h
+1
-1
No files found.
server/debugger.c
View file @
17cf8101
...
...
@@ -232,7 +232,7 @@ static int continue_debug_event( struct process *process, struct thread *thread,
{
struct
debug_event
*
event
=
thread
->
debug_event
;
if
(
process
->
debugger
!=
current
||
!
event
||
!
event
->
sent
)
if
(
process
->
debugger
!=
current
||
thread
->
process
!=
process
||
!
event
||
!
event
->
sent
)
{
/* not debugging this process, or no event pending */
set_error
(
ERROR_ACCESS_DENIED
);
/* FIXME */
...
...
@@ -244,9 +244,20 @@ static int continue_debug_event( struct process *process, struct thread *thread,
/* (we can get a continue on an exit thread/process event) */
struct
send_debug_event_request
*
req
=
get_req_ptr
(
thread
);
req
->
status
=
status
;
/* copy the context into the reply */
if
(
event
->
code
==
EXCEPTION_DEBUG_EVENT
)
memcpy
(
req
+
1
,
&
event
->
data
,
event_sizes
[
event
->
code
]
);
send_reply
(
thread
);
}
free_event
(
current
,
event
);
if
(
thread
->
exit_event
)
{
/* we still have a queued exit event, promote it to normal event */
thread
->
debug_event
=
thread
->
exit_event
;
thread
->
exit_event
=
NULL
;
}
resume_process
(
process
);
return
1
;
}
...
...
@@ -279,14 +290,13 @@ static struct debug_event *queue_debug_event( struct thread *debugger, struct th
if
(
thread
->
debug_event
)
{
/*
only exit events can replace others
*/
/*
exit events can happen while another one is still queued
*/
assert
(
code
==
EXIT_THREAD_DEBUG_EVENT
||
code
==
EXIT_PROCESS_DEBUG_EVENT
);
if
(
!
thread
->
debug_event
->
sent
)
unlink_event
(
debug_ctx
,
thread
->
debug_event
);
free_event
(
debugger
,
thread
->
debug_event
);
thread
->
exit_event
=
event
;
}
else
thread
->
debug_event
=
event
;
link_event
(
debug_ctx
,
event
);
thread
->
debug_event
=
event
;
suspend_process
(
thread
->
process
);
if
(
debug_ctx
->
waiting
)
{
...
...
@@ -317,7 +327,6 @@ int debugger_attach( struct process *process, struct thread *debugger )
if
(
!
debugger
->
debug_ctx
)
/* need to allocate a context */
{
assert
(
!
debugger
->
debug_first
);
if
(
!
(
debug_ctx
=
mem_alloc
(
sizeof
(
*
debug_ctx
)
)))
return
0
;
debug_ctx
->
owner
=
current
;
debug_ctx
->
waiting
=
0
;
...
...
@@ -326,44 +335,25 @@ int debugger_attach( struct process *process, struct thread *debugger )
debug_ctx
->
event_tail
=
NULL
;
debugger
->
debug_ctx
=
debug_ctx
;
}
process
->
debugger
=
debugger
;
process
->
debug_prev
=
NULL
;
process
->
debug_next
=
debugger
->
debug_first
;
debugger
->
debug_first
=
process
;
process
->
debugger
=
debugger
;
return
1
;
}
/* detach a process from its debugger thread */
static
void
debugger_detach
(
struct
process
*
process
)
{
struct
thread
*
debugger
=
process
->
debugger
;
assert
(
debugger
);
if
(
process
->
debug_next
)
process
->
debug_next
->
debug_prev
=
process
->
debug_prev
;
if
(
process
->
debug_prev
)
process
->
debug_prev
->
debug_next
=
process
->
debug_next
;
else
debugger
->
debug_first
=
process
->
debug_next
;
process
->
debugger
=
NULL
;
}
/* a thread is exiting */
void
debug_exit_thread
(
struct
thread
*
thread
,
int
exit_code
)
{
struct
thread
*
debugger
=
current
->
process
->
debugger
;
struct
thread
*
debugger
=
thread
->
process
->
debugger
;
struct
debug_ctx
*
debug_ctx
=
thread
->
debug_ctx
;
if
(
debugger
)
/* being debugged -> send an event to the debugger */
{
struct
debug_event_exit
event
;
event
.
exit_code
=
exit_code
;
if
(
!
thread
->
proc_next
&&
!
thread
->
proc_prev
)
{
assert
(
thread
->
process
->
thread_list
==
thread
);
/* this is the last thread, send an exit process event and cleanup */
queue_debug_event
(
debugger
,
current
,
EXIT_PROCESS_DEBUG_EVENT
,
&
event
);
debugger_detach
(
thread
->
process
);
}
else
queue_debug_event
(
debugger
,
current
,
EXIT_THREAD_DEBUG_EVENT
,
&
event
);
if
(
thread
->
process
->
running_threads
==
1
)
/* this is the last thread, send an exit process event */
queue_debug_event
(
debugger
,
thread
,
EXIT_PROCESS_DEBUG_EVENT
,
&
event
);
else
queue_debug_event
(
debugger
,
thread
,
EXIT_THREAD_DEBUG_EVENT
,
&
event
);
}
if
(
debug_ctx
)
/* this thread is a debugger */
...
...
@@ -371,7 +361,8 @@ void debug_exit_thread( struct thread *thread, int exit_code )
struct
debug_event
*
event
;
/* kill all debugged processes */
while
(
thread
->
debug_first
)
kill_process
(
thread
->
debug_first
,
exit_code
);
kill_debugged_processes
(
thread
,
exit_code
);
/* free all pending events */
while
((
event
=
debug_ctx
->
event_head
)
!=
NULL
)
{
...
...
server/process.c
View file @
17cf8101
...
...
@@ -60,8 +60,6 @@ static struct process *create_process( struct process *parent, struct new_proces
process
->
next
=
NULL
;
process
->
prev
=
NULL
;
process
->
thread_list
=
NULL
;
process
->
debug_next
=
NULL
;
process
->
debug_prev
=
NULL
;
process
->
debugger
=
NULL
;
process
->
handles
=
NULL
;
process
->
exit_code
=
0x103
;
/* STILL_ACTIVE */
...
...
@@ -292,6 +290,21 @@ void kill_process( struct process *process, int exit_code )
kill_thread
(
process
->
thread_list
,
exit_code
);
}
/* kill all processes being debugged by a given thread */
void
kill_debugged_processes
(
struct
thread
*
debugger
,
int
exit_code
)
{
for
(;;)
/* restart from the beginning of the list every time */
{
struct
process
*
process
=
first_process
;
/* find the first process being debugged by 'debugger' and still running */
while
(
process
&&
(
process
->
debugger
!=
debugger
||
!
process
->
running_threads
))
process
=
process
->
next
;
if
(
!
process
)
return
;
process
->
debugger
=
NULL
;
kill_process
(
process
,
exit_code
);
}
}
/* get all information about a process */
static
void
get_process_info
(
struct
process
*
process
,
struct
get_process_info_request
*
req
)
{
...
...
server/process.h
View file @
17cf8101
...
...
@@ -21,8 +21,6 @@ struct process
struct
process
*
next
;
/* system-wide process list */
struct
process
*
prev
;
struct
thread
*
thread_list
;
/* head of the thread list */
struct
process
*
debug_next
;
/* per-debugger process list */
struct
process
*
debug_prev
;
struct
thread
*
debugger
;
/* thread debugging this process */
struct
object
*
handles
;
/* handle entries */
int
exit_code
;
/* process exit code */
...
...
@@ -59,6 +57,7 @@ extern void remove_process_thread( struct process *process,
extern
void
suspend_process
(
struct
process
*
process
);
extern
void
resume_process
(
struct
process
*
process
);
extern
void
kill_process
(
struct
process
*
process
,
int
exit_code
);
extern
void
kill_debugged_processes
(
struct
thread
*
debugger
,
int
exit_code
);
extern
struct
process_snapshot
*
process_snap
(
int
*
count
);
#endif
/* __WINE_SERVER_PROCESS_H */
server/thread.c
View file @
17cf8101
...
...
@@ -112,8 +112,8 @@ static struct thread *create_thread( int fd, struct process *process, int suspen
thread
->
teb
=
NULL
;
thread
->
mutex
=
NULL
;
thread
->
debug_ctx
=
NULL
;
thread
->
debug_first
=
NULL
;
thread
->
debug_event
=
NULL
;
thread
->
exit_event
=
NULL
;
thread
->
wait
=
NULL
;
thread
->
apc
=
NULL
;
thread
->
apc_count
=
0
;
...
...
server/thread.h
View file @
17cf8101
...
...
@@ -40,8 +40,8 @@ struct thread
struct
process
*
process
;
struct
mutex
*
mutex
;
/* list of currently owned mutexes */
struct
debug_ctx
*
debug_ctx
;
/* debugger context if this thread is a debugger */
struct
process
*
debug_first
;
/* head of debugged processes list */
struct
debug_event
*
debug_event
;
/* pending debug event for this thread */
struct
debug_event
*
exit_event
;
/* pending debug exit event for this thread */
struct
thread_wait
*
wait
;
/* current wait condition if sleeping */
struct
thread_apc
*
apc
;
/* list of async procedure calls */
int
apc_count
;
/* number of outstanding APCs */
...
...
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