2 * Server-side debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
18 struct debug_event
*next
; /* event queue */
19 struct debug_event
*prev
;
20 struct thread
*thread
; /* thread which sent this event */
21 int sent
; /* already sent to the debugger? */
22 int code
; /* event code */
23 union debug_event_data data
; /* event data */
28 struct thread
*owner
; /* thread owning this debug context */
29 int waiting
; /* is thread waiting for an event? */
30 struct timeout_user
*timeout
; /* timeout user for wait timeout */
31 struct debug_event
*event_head
; /* head of pending events queue */
32 struct debug_event
*event_tail
; /* tail of pending events queue */
35 /* size of the event data */
36 static const int event_sizes
[] =
39 sizeof(struct debug_event_exception
), /* EXCEPTION_DEBUG_EVENT */
40 sizeof(struct debug_event_create_thread
), /* CREATE_THREAD_DEBUG_EVENT */
41 sizeof(struct debug_event_create_process
), /* CREATE_PROCESS_DEBUG_EVENT */
42 sizeof(struct debug_event_exit
), /* EXIT_THREAD_DEBUG_EVENT */
43 sizeof(struct debug_event_exit
), /* EXIT_PROCESS_DEBUG_EVENT */
44 sizeof(struct debug_event_load_dll
), /* LOAD_DLL_DEBUG_EVENT */
45 sizeof(struct debug_event_unload_dll
), /* UNLOAD_DLL_DEBUG_EVENT */
46 sizeof(struct debug_event_output_string
), /* OUTPUT_DEBUG_STRING_EVENT */
47 sizeof(struct debug_event_rip_info
) /* RIP_EVENT */
51 /* initialise the fields that do not need to be filled by the client */
52 static int fill_debug_event( struct thread
*debugger
, struct thread
*thread
,
53 struct debug_event
*event
)
57 /* some events need special handling */
60 case CREATE_THREAD_DEBUG_EVENT
:
61 if ((event
->data
.create_thread
.handle
= alloc_handle( debugger
->process
, thread
,
62 THREAD_GET_CONTEXT
| THREAD_SET_CONTEXT
| THREAD_SUSPEND_RESUME
, FALSE
)) == -1)
65 case CREATE_PROCESS_DEBUG_EVENT
:
66 if ((handle
= event
->data
.create_process
.file
) != -1)
68 if ((handle
= duplicate_handle( thread
->process
, handle
, debugger
->process
,
69 GENERIC_READ
, FALSE
, 0 )) == -1)
71 event
->data
.create_process
.file
= handle
;
73 if ((event
->data
.create_process
.process
= alloc_handle( debugger
->process
, thread
->process
,
74 PROCESS_VM_READ
| PROCESS_VM_WRITE
, FALSE
)) == -1)
76 if (handle
!= -1) close_handle( debugger
->process
, handle
);
79 if ((event
->data
.create_process
.thread
= alloc_handle( debugger
->process
, thread
,
80 THREAD_GET_CONTEXT
| THREAD_SET_CONTEXT
| THREAD_SUSPEND_RESUME
, FALSE
)) == -1)
82 if (handle
!= -1) close_handle( debugger
->process
, handle
);
83 close_handle( debugger
->process
, event
->data
.create_process
.process
);
87 case LOAD_DLL_DEBUG_EVENT
:
88 if ((handle
= event
->data
.load_dll
.handle
) != -1)
90 if ((handle
= duplicate_handle( thread
->process
, handle
, debugger
->process
,
91 GENERIC_READ
, FALSE
, 0 )) == -1)
93 event
->data
.load_dll
.handle
= handle
;
100 /* free a debug event structure */
101 static void free_event( struct debug_event
*event
)
105 case CREATE_THREAD_DEBUG_EVENT
:
106 close_handle( event
->thread
->process
, event
->data
.create_thread
.handle
);
108 case CREATE_PROCESS_DEBUG_EVENT
:
109 if (event
->data
.create_process
.file
!= -1)
110 close_handle( event
->thread
->process
, event
->data
.create_process
.file
);
111 close_handle( event
->thread
->process
, event
->data
.create_process
.thread
);
112 close_handle( event
->thread
->process
, event
->data
.create_process
.process
);
114 case LOAD_DLL_DEBUG_EVENT
:
115 if (event
->data
.load_dll
.handle
!= -1)
116 close_handle( event
->thread
->process
, event
->data
.load_dll
.handle
);
119 event
->thread
->debug_event
= NULL
;
120 release_object( event
->thread
);
124 /* unlink the first event from the queue */
125 static void unlink_event( struct debug_ctx
*debug_ctx
, struct debug_event
*event
)
127 if (event
->prev
) event
->prev
->next
= event
->next
;
128 else debug_ctx
->event_head
= event
->next
;
129 if (event
->next
) event
->next
->prev
= event
->prev
;
130 else debug_ctx
->event_tail
= event
->prev
;
131 event
->next
= event
->prev
= NULL
;
134 /* link an event at the end of the queue */
135 static void link_event( struct debug_ctx
*debug_ctx
, struct debug_event
*event
)
138 event
->prev
= debug_ctx
->event_tail
;
139 if (event
->prev
) event
->prev
->next
= event
;
140 else debug_ctx
->event_head
= event
;
141 debug_ctx
->event_tail
= event
;
144 /* send the first queue event as a reply */
145 static void build_event_reply( struct debug_ctx
*debug_ctx
)
147 struct debug_event
*event
= debug_ctx
->event_head
;
148 struct thread
*thread
= event
->thread
;
149 struct wait_debug_event_request
*req
= get_req_ptr( debug_ctx
->owner
);
152 assert( debug_ctx
->waiting
);
154 unlink_event( debug_ctx
, event
);
156 req
->code
= event
->code
;
157 req
->pid
= thread
->process
;
159 debug_ctx
->waiting
= 0;
160 if (debug_ctx
->timeout
)
162 remove_timeout_user( debug_ctx
->timeout
);
163 debug_ctx
->timeout
= NULL
;
165 debug_ctx
->owner
->error
= 0;
166 memcpy( req
+ 1, &event
->data
, event_sizes
[event
->code
] );
169 /* timeout callback while waiting for a debug event */
170 static void wait_event_timeout( void *ctx
)
172 struct debug_ctx
*debug_ctx
= (struct debug_ctx
*)ctx
;
173 struct wait_debug_event_request
*req
= get_req_ptr( debug_ctx
->owner
);
175 assert( debug_ctx
->waiting
);
180 debug_ctx
->waiting
= 0;
181 debug_ctx
->timeout
= NULL
;
182 debug_ctx
->owner
->error
= WAIT_TIMEOUT
;
183 send_reply( debug_ctx
->owner
);
186 /* wait for a debug event (or send a reply at once if one is pending) */
187 static int wait_for_debug_event( int timeout
)
189 struct debug_ctx
*debug_ctx
= current
->debug_ctx
;
192 if (!debug_ctx
) /* current thread is not a debugger */
194 set_error( ERROR_ACCESS_DENIED
); /* FIXME */
197 assert( !debug_ctx
->waiting
);
198 if (debug_ctx
->event_head
) /* already have a pending event */
200 debug_ctx
->waiting
= 1;
201 build_event_reply( debug_ctx
);
204 if (!timeout
) /* no event and we don't want to wait */
206 set_error( WAIT_TIMEOUT
);
209 if (timeout
!= -1) /* start the timeout */
211 make_timeout( &when
, timeout
);
212 if (!(debug_ctx
->timeout
= add_timeout_user( &when
, wait_event_timeout
, debug_ctx
)))
215 debug_ctx
->waiting
= 1;
216 current
->state
= SLEEPING
;
220 /* continue a debug event */
221 static int continue_debug_event( struct process
*process
, struct thread
*thread
, int status
)
223 struct debug_event
*event
= thread
->debug_event
;
225 if (process
->debugger
!= current
|| !event
|| !event
->sent
)
227 /* not debugging this process, or no event pending */
228 set_error( ERROR_ACCESS_DENIED
); /* FIXME */
231 if (thread
->state
!= TERMINATED
)
233 /* only send a reply if the thread is still there */
234 /* (we can get a continue on an exit thread/process event) */
235 struct send_debug_event_request
*req
= get_req_ptr( thread
);
236 req
->status
= status
;
237 send_reply( thread
);
240 resume_process( process
);
244 /* queue a debug event for a debugger */
245 static struct debug_event
*queue_debug_event( struct thread
*debugger
, struct thread
*thread
,
246 int code
, void *data
)
248 struct debug_ctx
*debug_ctx
= debugger
->debug_ctx
;
249 struct debug_event
*event
;
252 /* cannot queue a debug event for myself */
253 assert( debugger
->process
!= thread
->process
);
255 /* build the event */
256 if (!(event
= mem_alloc( sizeof(*event
) - sizeof(event
->data
) + event_sizes
[code
] )))
260 event
->thread
= (struct thread
*)grab_object( thread
);
261 memcpy( &event
->data
, data
, event_sizes
[code
] );
263 if (!fill_debug_event( debugger
, thread
, event
))
265 release_object( event
->thread
);
270 if (thread
->debug_event
)
272 /* only exit events can replace others */
273 assert( code
== EXIT_THREAD_DEBUG_EVENT
|| code
== EXIT_PROCESS_DEBUG_EVENT
);
274 if (!thread
->debug_event
->sent
) unlink_event( debug_ctx
, thread
->debug_event
);
275 free_event( thread
->debug_event
);
278 link_event( debug_ctx
, event
);
279 thread
->debug_event
= event
;
280 suspend_process( thread
->process
);
281 if (debug_ctx
->waiting
)
283 build_event_reply( debug_ctx
);
284 send_reply( debug_ctx
->owner
);
289 /* attach a process to a debugger thread */
290 int debugger_attach( struct process
*process
, struct thread
*debugger
)
292 struct debug_ctx
*debug_ctx
;
293 struct thread
*thread
;
295 if (process
->debugger
) /* already being debugged */
297 set_error( ERROR_ACCESS_DENIED
);
300 /* make sure we don't create a debugging loop */
301 for (thread
= debugger
; thread
; thread
= thread
->process
->debugger
)
302 if (thread
->process
== process
)
304 set_error( ERROR_ACCESS_DENIED
);
308 if (!debugger
->debug_ctx
) /* need to allocate a context */
310 assert( !debugger
->debug_first
);
311 if (!(debug_ctx
= mem_alloc( sizeof(*debug_ctx
) ))) return 0;
312 debug_ctx
->owner
= current
;
313 debug_ctx
->waiting
= 0;
314 debug_ctx
->timeout
= NULL
;
315 debug_ctx
->event_head
= NULL
;
316 debug_ctx
->event_tail
= NULL
;
317 debugger
->debug_ctx
= debug_ctx
;
319 process
->debugger
= debugger
;
320 process
->debug_prev
= NULL
;
321 process
->debug_next
= debugger
->debug_first
;
322 debugger
->debug_first
= process
;
326 /* detach a process from its debugger thread */
327 static void debugger_detach( struct process
*process
)
329 struct thread
*debugger
= process
->debugger
;
333 if (process
->debug_next
) process
->debug_next
->debug_prev
= process
->debug_prev
;
334 if (process
->debug_prev
) process
->debug_prev
->debug_next
= process
->debug_next
;
335 else debugger
->debug_first
= process
;
336 process
->debugger
= NULL
;
339 /* a thread is exiting */
340 void debug_exit_thread( struct thread
*thread
, int exit_code
)
342 struct thread
*debugger
= current
->process
->debugger
;
343 struct debug_ctx
*debug_ctx
= thread
->debug_ctx
;
345 if (debugger
) /* being debugged -> send an event to the debugger */
347 struct debug_event_exit event
;
348 event
.exit_code
= exit_code
;
349 if (!thread
->proc_next
&& !thread
->proc_prev
)
351 assert( thread
->process
->thread_list
== thread
);
352 /* this is the last thread, send an exit process event and cleanup */
353 queue_debug_event( debugger
, current
, EXIT_PROCESS_DEBUG_EVENT
, &event
);
354 debugger_detach( thread
->process
);
356 else queue_debug_event( debugger
, current
, EXIT_THREAD_DEBUG_EVENT
, &event
);
359 if (debug_ctx
) /* this thread is a debugger */
361 struct debug_event
*event
;
363 /* kill all debugged processes */
364 while (thread
->debug_first
) kill_process( thread
->debug_first
, exit_code
);
365 /* free all pending events */
366 while ((event
= debug_ctx
->event_head
) != NULL
)
368 unlink_event( debug_ctx
, event
);
371 /* remove the timeout */
372 if (debug_ctx
->timeout
) remove_timeout_user( debug_ctx
->timeout
);
373 thread
->debug_ctx
= NULL
;
378 /* Wait for a debug event */
379 DECL_HANDLER(wait_debug_event
)
381 if (!wait_for_debug_event( req
->timeout
))
389 /* Continue a debug event */
390 DECL_HANDLER(continue_debug_event
)
392 struct process
*process
= get_process_from_id( req
->pid
);
395 struct thread
*thread
= get_thread_from_id( req
->tid
);
398 continue_debug_event( process
, thread
, req
->status
);
399 release_object( thread
);
401 release_object( process
);
405 /* Start debugging an existing process */
406 DECL_HANDLER(debug_process
)
408 struct process
*process
= get_process_from_id( req
->pid
);
411 debugger_attach( process
, current
);
412 /* FIXME: should notice the debugged process somehow */
413 release_object( process
);
417 /* Send a debug event */
418 DECL_HANDLER(send_debug_event
)
420 struct thread
*debugger
= current
->process
->debugger
;
422 assert( !current
->debug_event
);
423 if ((req
->code
<= 0) || (req
->code
> RIP_EVENT
))
425 fatal_protocol_error( current
, "send_debug_event: bad code %d\n", req
->code
);
429 if (debugger
&& queue_debug_event( debugger
, current
, req
->code
, req
+ 1 ))
431 /* wait for continue_debug_event */
432 current
->state
= SLEEPING
;