Fixed ANSI C related compile problems.
[wine] / server / debugger.c
1 /*
2  * Server-side debugger functions
3  *
4  * Copyright (C) 1999 Alexandre Julliard
5  */
6
7 #include <assert.h>
8 #include <string.h>
9 #include <stdio.h>
10
11 #include "winbase.h"
12
13 #include "handle.h"
14 #include "process.h"
15 #include "thread.h"
16 #include "request.h"
17
18 enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_CONTINUED };
19
20 /* debug event */
21 struct debug_event
22 {
23     struct object          obj;       /* object header */
24     struct debug_event    *next;      /* event queue */
25     struct debug_event    *prev;
26     struct thread         *sender;    /* thread which sent this event */
27     struct thread         *debugger;  /* debugger thread receiving the event */
28     enum debug_event_state state;     /* event state */
29     int                    status;    /* continuation status */
30     debug_event_t          data;      /* event data */
31 };
32
33 /* debug context */
34 struct debug_ctx
35 {
36     struct object        obj;         /* object header */
37     struct debug_event  *event_head;  /* head of pending events queue */
38     struct debug_event  *event_tail;  /* tail of pending events queue */
39     struct debug_event  *to_send;     /* next event on the queue to send to debugger */
40 };
41
42
43 static void debug_event_dump( struct object *obj, int verbose );
44 static int debug_event_signaled( struct object *obj, struct thread *thread );
45 static void debug_event_destroy( struct object *obj );
46
47 static const struct object_ops debug_event_ops =
48 {
49     sizeof(struct debug_event),    /* size */
50     debug_event_dump,              /* dump */
51     add_queue,                     /* add_queue */
52     remove_queue,                  /* remove_queue */
53     debug_event_signaled,          /* signaled */
54     no_satisfied,                  /* satisfied */
55     NULL,                          /* get_poll_events */
56     NULL,                          /* poll_event */
57     no_read_fd,                    /* get_read_fd */
58     no_write_fd,                   /* get_write_fd */
59     no_flush,                      /* flush */
60     no_get_file_info,              /* get_file_info */
61     debug_event_destroy            /* destroy */
62 };
63
64 static void debug_ctx_dump( struct object *obj, int verbose );
65 static int debug_ctx_signaled( struct object *obj, struct thread *thread );
66 static void debug_ctx_destroy( struct object *obj );
67
68 static const struct object_ops debug_ctx_ops =
69 {
70     sizeof(struct debug_ctx),      /* size */
71     debug_ctx_dump,                /* dump */
72     add_queue,                     /* add_queue */
73     remove_queue,                  /* remove_queue */
74     debug_ctx_signaled,            /* signaled */
75     no_satisfied,                  /* satisfied */
76     NULL,                          /* get_poll_events */
77     NULL,                          /* poll_event */
78     no_read_fd,                    /* get_read_fd */
79     no_write_fd,                   /* get_write_fd */
80     no_flush,                      /* flush */
81     no_get_file_info,              /* get_file_info */
82     debug_ctx_destroy              /* destroy */
83 };
84
85
86 /* routines to build an event according to its type */
87
88 static int fill_exception_event( struct debug_event *event, void *arg )
89 {
90     memcpy( &event->data.info.exception, arg, sizeof(event->data.info.exception) );
91     return 1;
92 }
93
94 static int fill_create_thread_event( struct debug_event *event, void *arg )
95 {
96     struct process *debugger = event->debugger->process;
97     struct thread *thread = arg;
98     int handle;
99     
100     /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
101     if ((handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, FALSE )) == -1)
102         return 0;
103     event->data.info.create_thread.handle = handle;
104     event->data.info.create_thread.teb    = thread->teb;
105     event->data.info.create_thread.start  = thread->entry;
106     return 1;
107 }
108
109 static int fill_create_process_event( struct debug_event *event, void *arg )
110 {
111     struct process *debugger = event->debugger->process;
112     struct process *process = arg;
113     struct thread *thread = process->thread_list;
114     int handle;
115
116     /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
117     if ((handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, FALSE )) == -1)
118         return 0;
119     event->data.info.create_process.process = handle;
120
121     /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
122     if ((handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, FALSE )) == -1)
123     {
124         close_handle( debugger, event->data.info.create_process.process );
125         return 0;
126     }
127     event->data.info.create_process.thread = handle;
128
129     handle = -1;
130     if (process->exe.file &&
131         /* the doc says write access too, but this doesn't seem a good idea */
132         ((handle = alloc_handle( debugger, process->exe.file, GENERIC_READ, FALSE )) == -1))
133     {
134         close_handle( debugger, event->data.info.create_process.process );
135         close_handle( debugger, event->data.info.create_process.thread );
136         return 0;
137     }
138     event->data.info.create_process.file       = handle;
139     event->data.info.create_process.teb        = thread->teb;
140     event->data.info.create_process.base       = process->exe.base;
141     event->data.info.create_process.start      = thread->entry;
142     event->data.info.create_process.dbg_offset = process->exe.dbg_offset;
143     event->data.info.create_process.dbg_size   = process->exe.dbg_size;
144     event->data.info.create_process.name       = 0;
145     event->data.info.create_process.unicode    = 0;
146     return 1;
147 }
148
149 static int fill_exit_thread_event( struct debug_event *event, void *arg )
150 {
151     struct thread *thread = arg;
152     event->data.info.exit.exit_code = thread->exit_code;
153     return 1;
154 }
155
156 static int fill_exit_process_event( struct debug_event *event, void *arg )
157 {
158     struct process *process = arg;
159     event->data.info.exit.exit_code = process->exit_code;
160     return 1;
161 }
162
163 static int fill_load_dll_event( struct debug_event *event, void *arg )
164 {
165     struct process *debugger = event->debugger->process;
166     struct process_dll *dll = arg;
167     int handle = -1;
168
169     if (dll->file && (handle = alloc_handle( debugger, dll->file, GENERIC_READ, FALSE )) == -1)
170         return 0;
171     event->data.info.load_dll.handle     = handle;
172     event->data.info.load_dll.base       = dll->base;
173     event->data.info.load_dll.dbg_offset = dll->dbg_offset;
174     event->data.info.load_dll.dbg_size   = dll->dbg_size;
175     event->data.info.load_dll.name       = dll->name;
176     event->data.info.load_dll.unicode    = 0;
177     return 1;
178 }
179
180 static int fill_unload_dll_event( struct debug_event *event, void *arg )
181 {
182     event->data.info.unload_dll.base = arg;
183     return 1;
184 }
185
186 static int fill_output_debug_string_event( struct debug_event *event, void *arg )
187 {
188     struct output_debug_string_request *req = arg;
189     event->data.info.output_string.string  = req->string;
190     event->data.info.output_string.unicode = req->unicode;
191     event->data.info.output_string.length  = req->length;
192     return 1;
193 }
194
195 typedef int (*fill_event_func)( struct debug_event *event, void *arg );
196
197 #define NB_DEBUG_EVENTS OUTPUT_DEBUG_STRING_EVENT  /* RIP_EVENT not supported */
198
199 static const fill_event_func fill_debug_event[NB_DEBUG_EVENTS] =
200 {
201     fill_exception_event,            /* EXCEPTION_DEBUG_EVENT */
202     fill_create_thread_event,        /* CREATE_THREAD_DEBUG_EVENT */
203     fill_create_process_event,       /* CREATE_PROCESS_DEBUG_EVENT */
204     fill_exit_thread_event,          /* EXIT_THREAD_DEBUG_EVENT */
205     fill_exit_process_event,         /* EXIT_PROCESS_DEBUG_EVENT */
206     fill_load_dll_event,             /* LOAD_DLL_DEBUG_EVENT */
207     fill_unload_dll_event,           /* UNLOAD_DLL_DEBUG_EVENT */
208     fill_output_debug_string_event   /* OUTPUT_DEBUG_STRING_EVENT */
209 };
210
211
212 /* unlink the first event from the queue */
213 static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event )
214 {
215     if (event->prev) event->prev->next = event->next;
216     else debug_ctx->event_head = event->next;
217     if (event->next) event->next->prev = event->prev;
218     else debug_ctx->event_tail = event->prev;
219     if (debug_ctx->to_send == event) debug_ctx->to_send = event->next;
220     event->next = event->prev = NULL;
221     release_object( event );
222 }
223
224 /* link an event at the end of the queue */
225 static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event )
226 {
227     grab_object( event );
228     event->next = NULL;
229     event->prev = debug_ctx->event_tail;
230     debug_ctx->event_tail = event;
231     if (event->prev) event->prev->next = event;
232     else debug_ctx->event_head = event;
233     if (!debug_ctx->to_send)
234     {
235         debug_ctx->to_send = event;
236         wake_up( &debug_ctx->obj, 0 );
237     }
238 }
239
240 /* build a reply for the wait_debug_event request */
241 static void build_wait_debug_reply( struct thread *thread, struct object *obj, int signaled )
242 {
243     struct wait_debug_event_request *req = get_req_ptr( thread );
244
245     if (obj)
246     {
247         struct debug_ctx *debug_ctx = (struct debug_ctx *)obj; 
248         struct debug_event *event = debug_ctx->to_send;
249
250         /* the object that woke us has to be our debug context */
251         assert( obj->ops == &debug_ctx_ops );
252         assert( event );
253
254         event->state = EVENT_SENT;
255         debug_ctx->to_send = event->next;
256         req->event.code = event->data.code;
257         req->pid  = event->sender->process;
258         req->tid  = event->sender;
259         memcpy( &req->event, &event->data, sizeof(req->event) );
260     }
261     else  /* timeout or error */
262     {
263         req->event.code = 0;
264         req->pid  = 0;
265         req->tid  = 0;
266     }
267 }
268
269 /* build a reply for the send_event request */
270 static void build_exception_event_reply( struct thread *thread, struct object *obj, int signaled )
271 {
272     struct exception_event_request *req = get_req_ptr( thread );
273     struct debug_event *event = (struct debug_event *)obj;
274     assert( obj->ops == &debug_event_ops );
275     req->status = event->status;
276     thread->context = NULL;
277 }
278
279 static void debug_event_dump( struct object *obj, int verbose )
280 {
281     struct debug_event *debug_event = (struct debug_event *)obj;
282     assert( obj->ops == &debug_event_ops );
283     fprintf( stderr, "Debug event sender=%p code=%d state=%d\n",
284              debug_event->sender, debug_event->data.code, debug_event->state );
285 }
286
287 static int debug_event_signaled( struct object *obj, struct thread *thread )
288 {
289     struct debug_event *debug_event = (struct debug_event *)obj;
290     assert( obj->ops == &debug_event_ops );
291     return debug_event->state == EVENT_CONTINUED;
292 }
293
294 static void debug_event_destroy( struct object *obj )
295 {
296     struct debug_event *event = (struct debug_event *)obj;
297     assert( obj->ops == &debug_event_ops );
298
299     /* cannot still be in the queue */
300     assert( !event->next );
301     assert( !event->prev );
302
303     /* If the event has been sent already, the handles are now under the */
304     /* responsibility of the debugger process, so we don't touch them    */
305     if (event->state == EVENT_QUEUED)
306     {
307         struct process *debugger = event->debugger->process;
308         switch(event->data.code)
309         {
310         case CREATE_THREAD_DEBUG_EVENT:
311             close_handle( debugger, event->data.info.create_thread.handle );
312             break;
313         case CREATE_PROCESS_DEBUG_EVENT:
314             if (event->data.info.create_process.file != -1)
315                 close_handle( debugger, event->data.info.create_process.file );
316             close_handle( debugger, event->data.info.create_process.thread );
317             close_handle( debugger, event->data.info.create_process.process );
318             break;
319         case LOAD_DLL_DEBUG_EVENT:
320             if (event->data.info.load_dll.handle != -1)
321                 close_handle( debugger, event->data.info.load_dll.handle );
322             break;
323         }
324     }
325     release_object( event->sender );
326     release_object( event->debugger );
327 }
328
329 static void debug_ctx_dump( struct object *obj, int verbose )
330 {
331     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
332     assert( obj->ops == &debug_ctx_ops );
333     fprintf( stderr, "Debug context head=%p tail=%p to_send=%p\n",
334              debug_ctx->event_head, debug_ctx->event_tail, debug_ctx->to_send );
335 }
336
337 static int debug_ctx_signaled( struct object *obj, struct thread *thread )
338 {
339     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
340     assert( obj->ops == &debug_ctx_ops );
341     return debug_ctx->to_send != NULL;
342 }
343
344 static void debug_ctx_destroy( struct object *obj )
345 {
346     struct debug_event *event;
347     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
348     assert( obj->ops == &debug_ctx_ops );
349
350     /* free all pending events */
351     while ((event = debug_ctx->event_head) != NULL) unlink_event( debug_ctx, event );
352 }
353
354 /* wait for a debug event (or send a reply at once if one is pending) */
355 static int wait_for_debug_event( int timeout )
356 {
357     struct debug_ctx *debug_ctx = current->debug_ctx;
358     struct object *obj = &debug_ctx->obj;
359     int flags = 0;
360
361     if (!debug_ctx)  /* current thread is not a debugger */
362     {
363         set_error( STATUS_INVALID_HANDLE );
364         return 0;
365     }
366     if (timeout != -1) flags = SELECT_TIMEOUT;
367     return sleep_on( 1, &obj, flags, timeout, build_wait_debug_reply );
368 }
369
370 /* continue a debug event */
371 static int continue_debug_event( struct process *process, struct thread *thread, int status )
372 {
373     struct debug_event *event;
374     struct debug_ctx *debug_ctx = current->debug_ctx;
375
376     if (!debug_ctx || process->debugger != current || thread->process != process) goto error;
377
378     /* find the event in the queue */
379     for (event = debug_ctx->event_head; event; event = event->next)
380     {
381         if (event == debug_ctx->to_send) goto error;
382         if (event->sender == thread) break;
383     }
384     if (!event) goto error;
385
386     event->status = status;
387     event->state  = EVENT_CONTINUED;
388     wake_up( &event->obj, 0 );
389
390     unlink_event( debug_ctx, event );
391     resume_process( process );
392     return 1;
393  error:
394     /* not debugging this process, or no such event */
395     set_error( STATUS_ACCESS_DENIED );  /* FIXME */
396     return 0;
397 }
398
399 /* queue a debug event for a debugger */
400 static struct debug_event *queue_debug_event( struct thread *thread, int code, void *arg )
401 {
402     struct thread *debugger = thread->process->debugger;
403     struct debug_ctx *debug_ctx = debugger->debug_ctx;
404     struct debug_event *event;
405
406     assert( code > 0 && code <= NB_DEBUG_EVENTS );
407     assert( debug_ctx );
408     /* cannot queue a debug event for myself */
409     assert( debugger->process != thread->process );
410
411     /* build the event */
412     if (!(event = alloc_object( &debug_event_ops, -1 ))) return NULL;
413     event->next      = NULL;
414     event->prev      = NULL;
415     event->state     = EVENT_QUEUED;
416     event->sender    = (struct thread *)grab_object( thread );
417     event->debugger  = (struct thread *)grab_object( debugger );
418     event->data.code = code;
419
420     if (!fill_debug_event[code-1]( event, arg ))
421     {
422         event->data.code = -1;  /* make sure we don't attempt to close handles */
423         release_object( event );
424         return NULL;
425     }
426
427     link_event( debug_ctx, event );
428     suspend_process( thread->process );
429     return event;
430 }
431
432 /* generate a debug event from inside the server and queue it */
433 void generate_debug_event( struct thread *thread, int code, void *arg )
434 {
435     if (thread->process->debugger)
436     {
437         struct debug_event *event = queue_debug_event( thread, code, arg );
438         if (event) release_object( event );
439     }
440 }
441
442 /* attach a process to a debugger thread and suspend it */
443 static int debugger_attach( struct process *process, struct thread *debugger )
444 {
445     struct thread *thread;
446
447     if (process->debugger) goto error;  /* already being debugged */
448     if (process->init_event) goto error;  /* still starting up */
449
450     /* make sure we don't create a debugging loop */
451     for (thread = debugger; thread; thread = thread->process->debugger)
452         if (thread->process == process) goto error;
453
454     suspend_process( process );
455
456     /* we must have been able to attach all threads */
457     for (thread = process->thread_list; thread; thread = thread->proc_next)
458         if (!thread->attached)
459         {
460             fprintf( stderr, "%p not attached\n", thread );
461             resume_process( process );
462             goto error;
463         }
464
465     if (set_process_debugger( process, debugger )) return 1;
466     resume_process( process );
467     return 0;
468
469  error:
470     set_error( STATUS_ACCESS_DENIED );
471     return 0;
472 }
473
474 /* generate all startup events of a given process */
475 void generate_startup_debug_events( struct process *process )
476 {
477     struct process_dll *dll;
478     struct thread *thread = process->thread_list;
479
480     /* generate creation events */
481     generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, process );
482     while ((thread = thread->proc_next))
483         generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, thread );
484
485     /* generate dll events (in loading order, i.e. reverse list order) */
486     for (dll = &process->exe; dll->next; dll = dll->next);
487     while (dll != &process->exe)
488     {
489         generate_debug_event( process->thread_list, LOAD_DLL_DEBUG_EVENT, dll );
490         dll = dll->prev;
491     }
492 }
493
494 /* set the debugger of a given process */
495 int set_process_debugger( struct process *process, struct thread *debugger )
496 {
497     struct debug_ctx *debug_ctx;
498
499     assert( !process->debugger );
500
501     if (!debugger->debug_ctx)  /* need to allocate a context */
502     {
503         if (!(debug_ctx = alloc_object( &debug_ctx_ops, -1 ))) return 0;
504         debug_ctx->event_head = NULL;
505         debug_ctx->event_tail = NULL;
506         debug_ctx->to_send    = NULL;
507         debugger->debug_ctx = debug_ctx;
508     }
509     process->debugger = debugger;
510     return 1;
511 }
512
513 /* a thread is exiting */
514 void debug_exit_thread( struct thread *thread )
515 {
516     if (thread->debug_ctx)  /* this thread is a debugger */
517     {
518         /* kill all debugged processes */
519         kill_debugged_processes( thread, thread->exit_code );
520         release_object( thread->debug_ctx );
521         thread->debug_ctx = NULL;
522     }
523 }
524
525 /* Wait for a debug event */
526 DECL_HANDLER(wait_debug_event)
527 {
528     if (!wait_for_debug_event( req->timeout ))
529     {
530         req->event.code = 0;
531         req->pid = NULL;
532         req->tid = NULL;
533     }
534 }
535
536 /* Continue a debug event */
537 DECL_HANDLER(continue_debug_event)
538 {
539     struct process *process = get_process_from_id( req->pid );
540     if (process)
541     {
542         struct thread *thread = get_thread_from_id( req->tid );
543         if (thread)
544         {
545             continue_debug_event( process, thread, req->status );
546             release_object( thread );
547         }
548         release_object( process );
549     }
550 }
551
552 /* Start debugging an existing process */
553 DECL_HANDLER(debug_process)
554 {
555     struct debug_event_exception data;
556     struct debug_event *event;
557     struct process *process = get_process_from_id( req->pid );
558     if (!process) return;
559
560     if (debugger_attach( process, current ))
561     {
562         generate_startup_debug_events( process );
563         resume_process( process );
564
565         data.record.ExceptionCode    = EXCEPTION_BREAKPOINT;
566         data.record.ExceptionFlags   = EXCEPTION_CONTINUABLE;
567         data.record.ExceptionRecord  = NULL;
568         data.record.ExceptionAddress = process->thread_list->entry; /* FIXME */
569         data.record.NumberParameters = 0;
570         data.first = 1;
571         if ((event = queue_debug_event( process->thread_list, EXCEPTION_DEBUG_EVENT, &data )))
572             release_object( event );
573     }
574     release_object( process );
575 }
576
577 /* send an exception event */
578 DECL_HANDLER(exception_event)
579 {
580     if (current->process->debugger)
581     {
582         struct debug_event_exception data;
583         struct debug_event *event;
584
585         data.record = req->record;
586         data.first  = req->first;
587         if ((event = queue_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
588         {
589             struct object *obj = &event->obj;
590             current->context = &req->context;
591             sleep_on( 1, &obj, 0, -1, build_exception_event_reply );
592             release_object( event );
593         }
594     }
595 }
596
597 /* send an output string to the debugger */
598 DECL_HANDLER(output_debug_string)
599 {
600     if (current->process->debugger)
601     {
602         struct debug_event *event = queue_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, req );
603         if (event) release_object( event );
604     }
605 }