Made debug events and contexts standard objects.
[wine.git] / server / debugger.c
blob6e370e01d26171454da52b96e819a3363a21370d
1 /*
2 * Server-side debugger functions
4 * Copyright (C) 1999 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
11 #include "winbase.h"
12 #include "winerror.h"
14 #include "handle.h"
15 #include "process.h"
16 #include "thread.h"
17 #include "request.h"
19 enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_CONTINUED };
21 /* debug event */
22 struct debug_event
24 struct object obj; /* object header */
25 struct debug_event *next; /* event queue */
26 struct debug_event *prev;
27 struct thread *sender; /* thread which sent this event */
28 struct thread *debugger; /* debugger thread receiving the event */
29 enum debug_event_state state; /* event state */
30 int status; /* continuation status */
31 int code; /* event code */
32 union debug_event_data data; /* event data */
35 /* debug context */
36 struct debug_ctx
38 struct object obj; /* object header */
39 struct debug_event *event_head; /* head of pending events queue */
40 struct debug_event *event_tail; /* tail of pending events queue */
41 struct debug_event *to_send; /* next event on the queue to send to debugger */
45 static void debug_event_dump( struct object *obj, int verbose );
46 static int debug_event_signaled( struct object *obj, struct thread *thread );
47 static void debug_event_destroy( struct object *obj );
49 static const struct object_ops debug_event_ops =
51 sizeof(struct debug_event), /* size */
52 debug_event_dump, /* dump */
53 add_queue, /* add_queue */
54 remove_queue, /* remove_queue */
55 debug_event_signaled, /* signaled */
56 no_satisfied, /* satisfied */
57 NULL, /* get_poll_events */
58 NULL, /* poll_event */
59 no_read_fd, /* get_read_fd */
60 no_write_fd, /* get_write_fd */
61 no_flush, /* flush */
62 no_get_file_info, /* get_file_info */
63 debug_event_destroy /* destroy */
66 static void debug_ctx_dump( struct object *obj, int verbose );
67 static int debug_ctx_signaled( struct object *obj, struct thread *thread );
68 static void debug_ctx_destroy( struct object *obj );
70 static const struct object_ops debug_ctx_ops =
72 sizeof(struct debug_ctx), /* size */
73 debug_ctx_dump, /* dump */
74 add_queue, /* add_queue */
75 remove_queue, /* remove_queue */
76 debug_ctx_signaled, /* signaled */
77 no_satisfied, /* satisfied */
78 NULL, /* get_poll_events */
79 NULL, /* poll_event */
80 no_read_fd, /* get_read_fd */
81 no_write_fd, /* get_write_fd */
82 no_flush, /* flush */
83 no_get_file_info, /* get_file_info */
84 debug_ctx_destroy /* destroy */
87 /* size of the event data */
88 static const int event_sizes[] =
91 sizeof(struct debug_event_exception), /* EXCEPTION_DEBUG_EVENT */
92 sizeof(struct debug_event_create_thread), /* CREATE_THREAD_DEBUG_EVENT */
93 sizeof(struct debug_event_create_process), /* CREATE_PROCESS_DEBUG_EVENT */
94 sizeof(struct debug_event_exit), /* EXIT_THREAD_DEBUG_EVENT */
95 sizeof(struct debug_event_exit), /* EXIT_PROCESS_DEBUG_EVENT */
96 sizeof(struct debug_event_load_dll), /* LOAD_DLL_DEBUG_EVENT */
97 sizeof(struct debug_event_unload_dll), /* UNLOAD_DLL_DEBUG_EVENT */
98 sizeof(struct debug_event_output_string), /* OUTPUT_DEBUG_STRING_EVENT */
99 sizeof(struct debug_event_rip_info) /* RIP_EVENT */
103 /* initialise the fields that do not need to be filled by the client */
104 static int fill_debug_event( struct thread *debugger, struct thread *thread,
105 struct debug_event *event )
107 int handle;
109 /* some events need special handling */
110 switch(event->code)
112 case CREATE_THREAD_DEBUG_EVENT:
113 if ((event->data.create_thread.handle = alloc_handle( debugger->process, thread,
114 /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
115 THREAD_ALL_ACCESS, FALSE )) == -1)
116 return 0;
117 break;
118 case CREATE_PROCESS_DEBUG_EVENT:
119 if ((handle = event->data.create_process.file) != -1)
121 if ((handle = duplicate_handle( thread->process, handle, debugger->process,
122 GENERIC_READ, FALSE, 0 )) == -1)
123 return 0;
124 event->data.create_process.file = handle;
126 if ((event->data.create_process.process = alloc_handle( debugger->process, thread->process,
127 /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
128 PROCESS_ALL_ACCESS, FALSE )) == -1)
130 if (handle != -1) close_handle( debugger->process, handle );
131 return 0;
133 if ((event->data.create_process.thread = alloc_handle( debugger->process, thread,
134 /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
135 THREAD_ALL_ACCESS, FALSE )) == -1)
137 if (handle != -1) close_handle( debugger->process, handle );
138 close_handle( debugger->process, event->data.create_process.process );
139 return 0;
141 break;
142 case LOAD_DLL_DEBUG_EVENT:
143 if ((handle = event->data.load_dll.handle) != -1)
145 if ((handle = duplicate_handle( thread->process, handle, debugger->process,
146 GENERIC_READ, FALSE, 0 )) == -1)
147 return 0;
148 event->data.load_dll.handle = handle;
150 break;
152 return 1;
155 /* unlink the first event from the queue */
156 static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event )
158 if (event->prev) event->prev->next = event->next;
159 else debug_ctx->event_head = event->next;
160 if (event->next) event->next->prev = event->prev;
161 else debug_ctx->event_tail = event->prev;
162 if (debug_ctx->to_send == event) debug_ctx->to_send = event->next;
163 event->next = event->prev = NULL;
164 release_object( event );
167 /* link an event at the end of the queue */
168 static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event )
170 grab_object( event );
171 event->next = NULL;
172 event->prev = debug_ctx->event_tail;
173 debug_ctx->event_tail = event;
174 if (event->prev) event->prev->next = event;
175 else debug_ctx->event_head = event;
176 if (!debug_ctx->to_send)
178 debug_ctx->to_send = event;
179 wake_up( &debug_ctx->obj, 0 );
183 /* build a reply for the wait_debug_event request */
184 static void build_wait_debug_reply( struct thread *thread, struct object *obj, int signaled )
186 struct wait_debug_event_request *req = get_req_ptr( thread );
188 if (obj)
190 struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
191 struct debug_event *event = debug_ctx->to_send;
193 /* the object that woke us has to be our debug context */
194 assert( obj->ops == &debug_ctx_ops );
195 assert( event );
197 event->state = EVENT_SENT;
198 debug_ctx->to_send = event->next;
199 req->code = event->code;
200 req->pid = event->sender->process;
201 req->tid = event->sender;
202 memcpy( req + 1, &event->data, event_sizes[event->code] );
204 else /* timeout or error */
206 req->code = 0;
207 req->pid = 0;
208 req->tid = 0;
209 thread->error = signaled;
213 /* build a reply for the send_event request */
214 static void build_send_event_reply( struct thread *thread, struct object *obj, int signaled )
216 struct send_debug_event_request *req = get_req_ptr( thread );
217 struct debug_event *event = (struct debug_event *)obj;
218 assert( obj->ops == &debug_event_ops );
220 req->status = event->status;
221 /* copy the context into the reply */
222 if (event->code == EXCEPTION_DEBUG_EVENT)
223 memcpy( req + 1, &event->data, event_sizes[event->code] );
226 static void debug_event_dump( struct object *obj, int verbose )
228 struct debug_event *debug_event = (struct debug_event *)obj;
229 assert( obj->ops == &debug_event_ops );
230 fprintf( stderr, "Debug event sender=%p code=%d state=%d\n",
231 debug_event->sender, debug_event->code, debug_event->state );
234 static int debug_event_signaled( struct object *obj, struct thread *thread )
236 struct debug_event *debug_event = (struct debug_event *)obj;
237 assert( obj->ops == &debug_event_ops );
238 return debug_event->state == EVENT_CONTINUED;
241 static void debug_event_destroy( struct object *obj )
243 struct debug_event *event = (struct debug_event *)obj;
244 assert( obj->ops == &debug_event_ops );
246 /* cannot still be in the queue */
247 assert( !event->next );
248 assert( !event->prev );
250 /* If the event has been sent already, the handles are now under the */
251 /* responsibility of the debugger process, so we don't touch them */
252 if (event->state == EVENT_QUEUED)
254 struct process *debugger = event->debugger->process;
255 switch(event->code)
257 case CREATE_THREAD_DEBUG_EVENT:
258 close_handle( debugger, event->data.create_thread.handle );
259 break;
260 case CREATE_PROCESS_DEBUG_EVENT:
261 if (event->data.create_process.file != -1)
262 close_handle( debugger, event->data.create_process.file );
263 close_handle( debugger, event->data.create_process.thread );
264 close_handle( debugger, event->data.create_process.process );
265 break;
266 case LOAD_DLL_DEBUG_EVENT:
267 if (event->data.load_dll.handle != -1)
268 close_handle( debugger, event->data.load_dll.handle );
269 break;
272 release_object( event->sender );
273 release_object( event->debugger );
276 static void debug_ctx_dump( struct object *obj, int verbose )
278 struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
279 assert( obj->ops == &debug_ctx_ops );
280 fprintf( stderr, "Debug context head=%p tail=%p to_send=%p\n",
281 debug_ctx->event_head, debug_ctx->event_tail, debug_ctx->to_send );
284 static int debug_ctx_signaled( struct object *obj, struct thread *thread )
286 struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
287 assert( obj->ops == &debug_ctx_ops );
288 return debug_ctx->to_send != NULL;
291 static void debug_ctx_destroy( struct object *obj )
293 struct debug_event *event;
294 struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
295 assert( obj->ops == &debug_ctx_ops );
297 /* free all pending events */
298 while ((event = debug_ctx->event_head) != NULL) unlink_event( debug_ctx, event );
301 /* wait for a debug event (or send a reply at once if one is pending) */
302 static int wait_for_debug_event( int timeout )
304 struct debug_ctx *debug_ctx = current->debug_ctx;
305 struct object *obj = &debug_ctx->obj;
306 int flags = 0;
308 if (!debug_ctx) /* current thread is not a debugger */
310 set_error( ERROR_INVALID_HANDLE );
311 return 0;
313 if (timeout != -1) flags = SELECT_TIMEOUT;
314 return sleep_on( 1, &obj, flags, timeout, build_wait_debug_reply );
317 /* continue a debug event */
318 static int continue_debug_event( struct process *process, struct thread *thread, int status )
320 struct debug_event *event;
321 struct debug_ctx *debug_ctx = current->debug_ctx;
323 if (!debug_ctx || process->debugger != current || thread->process != process) goto error;
325 /* find the event in the queue */
326 for (event = debug_ctx->event_head; event; event = event->next)
328 if (event == debug_ctx->to_send) goto error;
329 if (event->sender == thread) break;
330 event = event->next;
332 if (!event) goto error;
334 event->status = status;
335 event->state = EVENT_CONTINUED;
336 wake_up( &event->obj, 0 );
338 unlink_event( debug_ctx, event );
339 resume_process( process );
340 return 1;
341 error:
342 /* not debugging this process, or no such event */
343 set_error( ERROR_ACCESS_DENIED ); /* FIXME */
344 return 0;
347 /* queue a debug event for a debugger */
348 static struct debug_event *queue_debug_event( struct thread *debugger, struct thread *thread,
349 int code, void *data )
351 struct debug_ctx *debug_ctx = debugger->debug_ctx;
352 struct debug_event *event;
354 assert( debug_ctx );
355 /* cannot queue a debug event for myself */
356 assert( debugger->process != thread->process );
358 /* build the event */
359 if (!(event = alloc_object( &debug_event_ops, -1 ))) return NULL;
360 event->next = NULL;
361 event->prev = NULL;
362 event->state = EVENT_QUEUED;
363 event->code = code;
364 event->sender = (struct thread *)grab_object( thread );
365 event->debugger = (struct thread *)grab_object( debugger );
366 memcpy( &event->data, data, event_sizes[code] );
368 if (!fill_debug_event( debugger, thread, event ))
370 event->code = -1; /* make sure we don't attempt to close handles */
371 release_object( event );
372 return NULL;
375 link_event( debug_ctx, event );
376 suspend_process( thread->process );
377 return event;
380 /* attach a process to a debugger thread */
381 int debugger_attach( struct process *process, struct thread *debugger )
383 struct debug_ctx *debug_ctx;
384 struct thread *thread;
386 if (process->debugger) /* already being debugged */
388 set_error( ERROR_ACCESS_DENIED );
389 return 0;
391 /* make sure we don't create a debugging loop */
392 for (thread = debugger; thread; thread = thread->process->debugger)
393 if (thread->process == process)
395 set_error( ERROR_ACCESS_DENIED );
396 return 0;
399 if (!debugger->debug_ctx) /* need to allocate a context */
401 if (!(debug_ctx = alloc_object( &debug_ctx_ops, -1 ))) return 0;
402 debug_ctx->event_head = NULL;
403 debug_ctx->event_tail = NULL;
404 debug_ctx->to_send = NULL;
405 debugger->debug_ctx = debug_ctx;
407 process->debugger = debugger;
408 return 1;
411 /* a thread is exiting */
412 void debug_exit_thread( struct thread *thread, int exit_code )
414 struct thread *debugger = thread->process->debugger;
415 struct debug_ctx *debug_ctx = thread->debug_ctx;
417 if (debugger) /* being debugged -> send an event to the debugger */
419 struct debug_event *event;
420 struct debug_event_exit exit;
421 exit.exit_code = exit_code;
422 if (thread->process->running_threads == 1)
423 /* this is the last thread, send an exit process event */
424 event = queue_debug_event( debugger, thread, EXIT_PROCESS_DEBUG_EVENT, &exit );
425 else
426 event = queue_debug_event( debugger, thread, EXIT_THREAD_DEBUG_EVENT, &exit );
427 if (event) release_object( event );
430 if (debug_ctx) /* this thread is a debugger */
432 /* kill all debugged processes */
433 kill_debugged_processes( thread, exit_code );
434 thread->debug_ctx = NULL;
435 release_object( debug_ctx );
439 /* Wait for a debug event */
440 DECL_HANDLER(wait_debug_event)
442 if (!wait_for_debug_event( req->timeout ))
444 req->code = 0;
445 req->pid = NULL;
446 req->tid = NULL;
450 /* Continue a debug event */
451 DECL_HANDLER(continue_debug_event)
453 struct process *process = get_process_from_id( req->pid );
454 if (process)
456 struct thread *thread = get_thread_from_id( req->tid );
457 if (thread)
459 continue_debug_event( process, thread, req->status );
460 release_object( thread );
462 release_object( process );
466 /* Start debugging an existing process */
467 DECL_HANDLER(debug_process)
469 struct process *process = get_process_from_id( req->pid );
470 if (process)
472 debugger_attach( process, current );
473 /* FIXME: should notify the debugged process somehow */
474 release_object( process );
478 /* Send a debug event */
479 DECL_HANDLER(send_debug_event)
481 struct thread *debugger = current->process->debugger;
482 struct debug_event *event;
484 if ((req->code <= 0) || (req->code > RIP_EVENT))
486 fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code );
487 return;
489 req->status = 0;
490 if (debugger && ((event = queue_debug_event( debugger, current, req->code, req + 1 ))))
492 /* wait for continue_debug_event */
493 struct object *obj = &event->obj;
494 sleep_on( 1, &obj, 0, -1, build_send_event_reply );
495 release_object( event );