2 * Server-side debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
20 struct debug_event
*next
; /* event queue */
21 struct debug_event
*prev
;
22 struct thread
*thread
; /* thread which sent this event */
23 int sent
; /* already sent to the debugger? */
24 int code
; /* event code */
25 union debug_event_data data
; /* event data */
30 struct thread
*owner
; /* thread owning this debug context */
31 int waiting
; /* is thread waiting for an event? */
32 struct timeout_user
*timeout
; /* timeout user for wait timeout */
33 struct debug_event
*event_head
; /* head of pending events queue */
34 struct debug_event
*event_tail
; /* tail of pending events queue */
37 /* size of the event data */
38 static const int event_sizes
[] =
41 sizeof(struct debug_event_exception
), /* EXCEPTION_DEBUG_EVENT */
42 sizeof(struct debug_event_create_thread
), /* CREATE_THREAD_DEBUG_EVENT */
43 sizeof(struct debug_event_create_process
), /* CREATE_PROCESS_DEBUG_EVENT */
44 sizeof(struct debug_event_exit
), /* EXIT_THREAD_DEBUG_EVENT */
45 sizeof(struct debug_event_exit
), /* EXIT_PROCESS_DEBUG_EVENT */
46 sizeof(struct debug_event_load_dll
), /* LOAD_DLL_DEBUG_EVENT */
47 sizeof(struct debug_event_unload_dll
), /* UNLOAD_DLL_DEBUG_EVENT */
48 sizeof(struct debug_event_output_string
), /* OUTPUT_DEBUG_STRING_EVENT */
49 sizeof(struct debug_event_rip_info
) /* RIP_EVENT */
53 /* initialise the fields that do not need to be filled by the client */
54 static int fill_debug_event( struct thread
*debugger
, struct thread
*thread
,
55 struct debug_event
*event
)
59 /* some events need special handling */
62 case CREATE_THREAD_DEBUG_EVENT
:
63 if ((event
->data
.create_thread
.handle
= alloc_handle( debugger
->process
, thread
,
64 THREAD_GET_CONTEXT
| THREAD_SET_CONTEXT
| THREAD_SUSPEND_RESUME
, FALSE
)) == -1)
67 case CREATE_PROCESS_DEBUG_EVENT
:
68 if ((handle
= event
->data
.create_process
.file
) != -1)
70 if ((handle
= duplicate_handle( thread
->process
, handle
, debugger
->process
,
71 GENERIC_READ
, FALSE
, 0 )) == -1)
73 event
->data
.create_process
.file
= handle
;
75 if ((event
->data
.create_process
.process
= alloc_handle( debugger
->process
, thread
->process
,
76 PROCESS_VM_READ
| PROCESS_VM_WRITE
, FALSE
)) == -1)
78 if (handle
!= -1) close_handle( debugger
->process
, handle
);
81 if ((event
->data
.create_process
.thread
= alloc_handle( debugger
->process
, thread
,
82 THREAD_GET_CONTEXT
| THREAD_SET_CONTEXT
| THREAD_SUSPEND_RESUME
, FALSE
)) == -1)
84 if (handle
!= -1) close_handle( debugger
->process
, handle
);
85 close_handle( debugger
->process
, event
->data
.create_process
.process
);
89 case LOAD_DLL_DEBUG_EVENT
:
90 if ((handle
= event
->data
.load_dll
.handle
) != -1)
92 if ((handle
= duplicate_handle( thread
->process
, handle
, debugger
->process
,
93 GENERIC_READ
, FALSE
, 0 )) == -1)
95 event
->data
.load_dll
.handle
= handle
;
102 /* free a debug event structure */
103 static void free_event( struct debug_event
*event
)
107 case CREATE_THREAD_DEBUG_EVENT
:
108 close_handle( event
->thread
->process
, event
->data
.create_thread
.handle
);
110 case CREATE_PROCESS_DEBUG_EVENT
:
111 if (event
->data
.create_process
.file
!= -1)
112 close_handle( event
->thread
->process
, event
->data
.create_process
.file
);
113 close_handle( event
->thread
->process
, event
->data
.create_process
.thread
);
114 close_handle( event
->thread
->process
, event
->data
.create_process
.process
);
116 case LOAD_DLL_DEBUG_EVENT
:
117 if (event
->data
.load_dll
.handle
!= -1)
118 close_handle( event
->thread
->process
, event
->data
.load_dll
.handle
);
121 event
->thread
->debug_event
= NULL
;
122 release_object( event
->thread
);
126 /* unlink the first event from the queue */
127 static void unlink_event( struct debug_ctx
*debug_ctx
, struct debug_event
*event
)
129 if (event
->prev
) event
->prev
->next
= event
->next
;
130 else debug_ctx
->event_head
= event
->next
;
131 if (event
->next
) event
->next
->prev
= event
->prev
;
132 else debug_ctx
->event_tail
= event
->prev
;
133 event
->next
= event
->prev
= NULL
;
136 /* link an event at the end of the queue */
137 static void link_event( struct debug_ctx
*debug_ctx
, struct debug_event
*event
)
140 event
->prev
= debug_ctx
->event_tail
;
141 if (event
->prev
) event
->prev
->next
= event
;
142 else debug_ctx
->event_head
= event
;
143 debug_ctx
->event_tail
= event
;
146 /* send the first queue event as a reply */
147 static void build_event_reply( struct debug_ctx
*debug_ctx
)
149 struct debug_event
*event
= debug_ctx
->event_head
;
150 struct thread
*thread
= event
->thread
;
151 struct wait_debug_event_request
*req
= get_req_ptr( debug_ctx
->owner
);
154 assert( debug_ctx
->waiting
);
156 unlink_event( debug_ctx
, event
);
158 req
->code
= event
->code
;
159 req
->pid
= thread
->process
;
161 debug_ctx
->waiting
= 0;
162 if (debug_ctx
->timeout
)
164 remove_timeout_user( debug_ctx
->timeout
);
165 debug_ctx
->timeout
= NULL
;
167 debug_ctx
->owner
->error
= 0;
168 memcpy( req
+ 1, &event
->data
, event_sizes
[event
->code
] );
171 /* timeout callback while waiting for a debug event */
172 static void wait_event_timeout( void *ctx
)
174 struct debug_ctx
*debug_ctx
= (struct debug_ctx
*)ctx
;
175 struct wait_debug_event_request
*req
= get_req_ptr( debug_ctx
->owner
);
177 assert( debug_ctx
->waiting
);
182 debug_ctx
->waiting
= 0;
183 debug_ctx
->timeout
= NULL
;
184 debug_ctx
->owner
->error
= WAIT_TIMEOUT
;
185 send_reply( debug_ctx
->owner
);
188 /* wait for a debug event (or send a reply at once if one is pending) */
189 static int wait_for_debug_event( int timeout
)
191 struct debug_ctx
*debug_ctx
= current
->debug_ctx
;
194 if (!debug_ctx
) /* current thread is not a debugger */
196 set_error( ERROR_ACCESS_DENIED
); /* FIXME */
199 assert( !debug_ctx
->waiting
);
200 if (debug_ctx
->event_head
) /* already have a pending event */
202 debug_ctx
->waiting
= 1;
203 build_event_reply( debug_ctx
);
206 if (!timeout
) /* no event and we don't want to wait */
208 set_error( WAIT_TIMEOUT
);
211 if (timeout
!= -1) /* start the timeout */
213 make_timeout( &when
, timeout
);
214 if (!(debug_ctx
->timeout
= add_timeout_user( &when
, wait_event_timeout
, debug_ctx
)))
217 debug_ctx
->waiting
= 1;
218 current
->state
= SLEEPING
;
222 /* continue a debug event */
223 static int continue_debug_event( struct process
*process
, struct thread
*thread
, int status
)
225 struct debug_event
*event
= thread
->debug_event
;
227 if (process
->debugger
!= current
|| !event
|| !event
->sent
)
229 /* not debugging this process, or no event pending */
230 set_error( ERROR_ACCESS_DENIED
); /* FIXME */
233 if (thread
->state
!= TERMINATED
)
235 /* only send a reply if the thread is still there */
236 /* (we can get a continue on an exit thread/process event) */
237 struct send_debug_event_request
*req
= get_req_ptr( thread
);
238 req
->status
= status
;
239 send_reply( thread
);
242 resume_process( process
);
246 /* queue a debug event for a debugger */
247 static struct debug_event
*queue_debug_event( struct thread
*debugger
, struct thread
*thread
,
248 int code
, void *data
)
250 struct debug_ctx
*debug_ctx
= debugger
->debug_ctx
;
251 struct debug_event
*event
;
254 /* cannot queue a debug event for myself */
255 assert( debugger
->process
!= thread
->process
);
257 /* build the event */
258 if (!(event
= mem_alloc( sizeof(*event
) - sizeof(event
->data
) + event_sizes
[code
] )))
262 event
->thread
= (struct thread
*)grab_object( thread
);
263 memcpy( &event
->data
, data
, event_sizes
[code
] );
265 if (!fill_debug_event( debugger
, thread
, event
))
267 release_object( event
->thread
);
272 if (thread
->debug_event
)
274 /* only exit events can replace others */
275 assert( code
== EXIT_THREAD_DEBUG_EVENT
|| code
== EXIT_PROCESS_DEBUG_EVENT
);
276 if (!thread
->debug_event
->sent
) unlink_event( debug_ctx
, thread
->debug_event
);
277 free_event( thread
->debug_event
);
280 link_event( debug_ctx
, event
);
281 thread
->debug_event
= event
;
282 suspend_process( thread
->process
);
283 if (debug_ctx
->waiting
)
285 build_event_reply( debug_ctx
);
286 send_reply( debug_ctx
->owner
);
291 /* attach a process to a debugger thread */
292 int debugger_attach( struct process
*process
, struct thread
*debugger
)
294 struct debug_ctx
*debug_ctx
;
295 struct thread
*thread
;
297 if (process
->debugger
) /* already being debugged */
299 set_error( ERROR_ACCESS_DENIED
);
302 /* make sure we don't create a debugging loop */
303 for (thread
= debugger
; thread
; thread
= thread
->process
->debugger
)
304 if (thread
->process
== process
)
306 set_error( ERROR_ACCESS_DENIED
);
310 if (!debugger
->debug_ctx
) /* need to allocate a context */
312 assert( !debugger
->debug_first
);
313 if (!(debug_ctx
= mem_alloc( sizeof(*debug_ctx
) ))) return 0;
314 debug_ctx
->owner
= current
;
315 debug_ctx
->waiting
= 0;
316 debug_ctx
->timeout
= NULL
;
317 debug_ctx
->event_head
= NULL
;
318 debug_ctx
->event_tail
= NULL
;
319 debugger
->debug_ctx
= debug_ctx
;
321 process
->debugger
= debugger
;
322 process
->debug_prev
= NULL
;
323 process
->debug_next
= debugger
->debug_first
;
324 debugger
->debug_first
= process
;
328 /* detach a process from its debugger thread */
329 static void debugger_detach( struct process
*process
)
331 struct thread
*debugger
= process
->debugger
;
335 if (process
->debug_next
) process
->debug_next
->debug_prev
= process
->debug_prev
;
336 if (process
->debug_prev
) process
->debug_prev
->debug_next
= process
->debug_next
;
337 else debugger
->debug_first
= process
;
338 process
->debugger
= NULL
;
341 /* a thread is exiting */
342 void debug_exit_thread( struct thread
*thread
, int exit_code
)
344 struct thread
*debugger
= current
->process
->debugger
;
345 struct debug_ctx
*debug_ctx
= thread
->debug_ctx
;
347 if (debugger
) /* being debugged -> send an event to the debugger */
349 struct debug_event_exit event
;
350 event
.exit_code
= exit_code
;
351 if (!thread
->proc_next
&& !thread
->proc_prev
)
353 assert( thread
->process
->thread_list
== thread
);
354 /* this is the last thread, send an exit process event and cleanup */
355 queue_debug_event( debugger
, current
, EXIT_PROCESS_DEBUG_EVENT
, &event
);
356 debugger_detach( thread
->process
);
358 else queue_debug_event( debugger
, current
, EXIT_THREAD_DEBUG_EVENT
, &event
);
361 if (debug_ctx
) /* this thread is a debugger */
363 struct debug_event
*event
;
365 /* kill all debugged processes */
366 while (thread
->debug_first
) kill_process( thread
->debug_first
, exit_code
);
367 /* free all pending events */
368 while ((event
= debug_ctx
->event_head
) != NULL
)
370 unlink_event( debug_ctx
, event
);
373 /* remove the timeout */
374 if (debug_ctx
->timeout
) remove_timeout_user( debug_ctx
->timeout
);
375 thread
->debug_ctx
= NULL
;
380 /* Wait for a debug event */
381 DECL_HANDLER(wait_debug_event
)
383 if (!wait_for_debug_event( req
->timeout
))
391 /* Continue a debug event */
392 DECL_HANDLER(continue_debug_event
)
394 struct process
*process
= get_process_from_id( req
->pid
);
397 struct thread
*thread
= get_thread_from_id( req
->tid
);
400 continue_debug_event( process
, thread
, req
->status
);
401 release_object( thread
);
403 release_object( process
);
407 /* Start debugging an existing process */
408 DECL_HANDLER(debug_process
)
410 struct process
*process
= get_process_from_id( req
->pid
);
413 debugger_attach( process
, current
);
414 /* FIXME: should notice the debugged process somehow */
415 release_object( process
);
419 /* Send a debug event */
420 DECL_HANDLER(send_debug_event
)
422 struct thread
*debugger
= current
->process
->debugger
;
424 assert( !current
->debug_event
);
425 if ((req
->code
<= 0) || (req
->code
> RIP_EVENT
))
427 fatal_protocol_error( current
, "send_debug_event: bad code %d\n", req
->code
);
431 if (debugger
&& queue_debug_event( debugger
, current
, req
->code
, req
+ 1 ))
433 /* wait for continue_debug_event */
434 current
->state
= SLEEPING
;