Made IShellFolder::fnParseDisplayName return a relative pidl.
[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 "winbase.h"
9 #include "winerror.h"
10
11 #include "handle.h"
12 #include "process.h"
13 #include "thread.h"
14 #include "request.h"
15
16 struct debug_event
17 {
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 */
24 };
25
26 struct debug_ctx
27 {
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 */
33 };
34
35 /* size of the event data */
36 static const int event_sizes[] =
37 {
38     0,
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 */
48 };
49
50
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 )
54 {
55     int handle;
56
57     /* some events need special handling */
58     switch(event->code)
59     {
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)
63             return 0;
64         break;
65     case CREATE_PROCESS_DEBUG_EVENT:
66         if ((handle = event->data.create_process.file) != -1)
67         {
68             if ((handle = duplicate_handle( thread->process, handle, debugger->process,
69                                             GENERIC_READ, FALSE, 0 )) == -1)
70                 return 0;
71             event->data.create_process.file = handle;
72         }
73         if ((event->data.create_process.process = alloc_handle( debugger->process, thread->process,
74                                               PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE )) == -1)
75         {
76             if (handle != -1) close_handle( debugger->process, handle );
77             return 0;
78         }
79         if ((event->data.create_process.thread = alloc_handle( debugger->process, thread,
80                   THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE )) == -1)
81         {
82             if (handle != -1) close_handle( debugger->process, handle );
83             close_handle( debugger->process, event->data.create_process.process );
84             return 0;
85         }
86         break;
87     case LOAD_DLL_DEBUG_EVENT:
88         if ((handle = event->data.load_dll.handle) != -1)
89         {
90             if ((handle = duplicate_handle( thread->process, handle, debugger->process,
91                                             GENERIC_READ, FALSE, 0 )) == -1)
92                 return 0;
93             event->data.load_dll.handle = handle;
94         }
95         break;
96     }
97     return 1;
98 }
99
100 /* free a debug event structure */
101 static void free_event( struct debug_event *event )
102 {
103     switch(event->code)
104     {
105     case CREATE_THREAD_DEBUG_EVENT:
106         close_handle( event->thread->process, event->data.create_thread.handle );
107         break;
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 );
113         break;
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 );
117         break;
118     }
119     event->thread->debug_event = NULL;
120     release_object( event->thread );
121     free( event );
122 }
123
124 /* unlink the first event from the queue */
125 static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event )
126 {
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;
132 }
133
134 /* link an event at the end of the queue */
135 static void link_event( struct debug_ctx *debug_ctx, struct debug_event *event )
136 {
137     event->next = NULL;
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;
142 }
143
144 /* send the first queue event as a reply */
145 static void build_event_reply( struct debug_ctx *debug_ctx )
146 {
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 );
150
151     assert( event );
152     assert( debug_ctx->waiting );
153
154     unlink_event( debug_ctx, event );
155     event->sent = 1;
156     req->code = event->code;
157     req->pid  = thread->process;
158     req->tid  = thread;
159     debug_ctx->waiting = 0;
160     if (debug_ctx->timeout)
161     {
162         remove_timeout_user( debug_ctx->timeout );
163         debug_ctx->timeout = NULL;
164     }
165     debug_ctx->owner->error = 0;
166     memcpy( req + 1, &event->data, event_sizes[event->code] );
167 }
168
169 /* timeout callback while waiting for a debug event */
170 static void wait_event_timeout( void *ctx )
171 {
172     struct debug_ctx *debug_ctx = (struct debug_ctx *)ctx;
173     struct wait_debug_event_request *req = get_req_ptr( debug_ctx->owner );
174
175     assert( debug_ctx->waiting );
176
177     req->code = 0;
178     req->pid  = 0;
179     req->tid  = 0;
180     debug_ctx->waiting = 0;
181     debug_ctx->timeout = NULL;
182     debug_ctx->owner->error = WAIT_TIMEOUT;
183     send_reply( debug_ctx->owner );
184 }
185
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 )
188 {
189     struct debug_ctx *debug_ctx = current->debug_ctx;
190     struct timeval when;
191
192     if (!debug_ctx)  /* current thread is not a debugger */
193     {
194         set_error( ERROR_ACCESS_DENIED ); /* FIXME */
195         return 0;
196     }
197     assert( !debug_ctx->waiting );
198     if (debug_ctx->event_head)  /* already have a pending event */
199     {
200         debug_ctx->waiting = 1;
201         build_event_reply( debug_ctx );
202         return 1;
203     }
204     if (!timeout)  /* no event and we don't want to wait */
205     {
206         set_error( WAIT_TIMEOUT );
207         return 0;
208     }
209     if (timeout != -1)  /* start the timeout */
210     {
211         make_timeout( &when, timeout );
212         if (!(debug_ctx->timeout = add_timeout_user( &when, wait_event_timeout, debug_ctx )))
213             return 0;
214     }
215     debug_ctx->waiting = 1;
216     current->state = SLEEPING;
217     return 1;
218 }
219
220 /* continue a debug event */
221 static int continue_debug_event( struct process *process, struct thread *thread, int status )
222 {
223     struct debug_event *event = thread->debug_event;
224
225     if (process->debugger != current || !event || !event->sent)
226     {
227         /* not debugging this process, or no event pending */
228         set_error( ERROR_ACCESS_DENIED );  /* FIXME */
229         return 0;
230     }
231     if (thread->state != TERMINATED)
232     {
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 );
238     }
239     free_event( event );
240     resume_process( process );
241     return 1;
242 }
243
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 )
247 {
248     struct debug_ctx *debug_ctx = debugger->debug_ctx;
249     struct debug_event *event;
250
251     assert( debug_ctx );
252     /* cannot queue a debug event for myself */
253     assert( debugger->process != thread->process );
254
255     /* build the event */
256     if (!(event = mem_alloc( sizeof(*event) - sizeof(event->data) + event_sizes[code] )))
257         return NULL;
258     event->sent   = 0;
259     event->code   = code;
260     event->thread = (struct thread *)grab_object( thread );
261     memcpy( &event->data, data, event_sizes[code] );
262
263     if (!fill_debug_event( debugger, thread, event ))
264     {
265         release_object( event->thread );
266         free( event );
267         return NULL;
268     }
269
270     if (thread->debug_event)
271     {
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 );
276     }
277
278     link_event( debug_ctx, event );
279     thread->debug_event = event;
280     suspend_process( thread->process );
281     if (debug_ctx->waiting)
282     {
283         build_event_reply( debug_ctx );
284         send_reply( debug_ctx->owner );
285     }
286     return event;
287 }
288
289 /* attach a process to a debugger thread */
290 int debugger_attach( struct process *process, struct thread *debugger )
291 {
292     struct debug_ctx *debug_ctx;
293     struct thread *thread;
294
295     if (process->debugger)  /* already being debugged */
296     {
297         set_error( ERROR_ACCESS_DENIED );
298         return 0;
299     }
300     /* make sure we don't create a debugging loop */
301     for (thread = debugger; thread; thread = thread->process->debugger)
302         if (thread->process == process)
303         {
304             set_error( ERROR_ACCESS_DENIED );
305             return 0;
306         }
307
308     if (!debugger->debug_ctx)  /* need to allocate a context */
309     {
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;
318     }
319     process->debugger   = debugger;
320     process->debug_prev = NULL;
321     process->debug_next = debugger->debug_first;
322     debugger->debug_first = process;
323     return 1;
324 }
325
326 /* detach a process from its debugger thread */
327 static void debugger_detach( struct process *process )
328 {
329     struct thread *debugger = process->debugger;
330
331     assert( debugger );
332
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;
337 }
338
339 /* a thread is exiting */
340 void debug_exit_thread( struct thread *thread, int exit_code )
341 {
342     struct thread *debugger = current->process->debugger;
343     struct debug_ctx *debug_ctx = thread->debug_ctx;
344
345     if (debugger)  /* being debugged -> send an event to the debugger */
346     {
347         struct debug_event_exit event;
348         event.exit_code = exit_code;
349         if (!thread->proc_next && !thread->proc_prev)
350         {
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 );
355         }
356         else queue_debug_event( debugger, current, EXIT_THREAD_DEBUG_EVENT, &event );
357     }
358
359     if (debug_ctx)  /* this thread is a debugger */
360     {
361         struct debug_event *event;
362
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)
367         {
368             unlink_event( debug_ctx, event );
369             free_event( event );
370         }
371         /* remove the timeout */
372         if (debug_ctx->timeout) remove_timeout_user( debug_ctx->timeout );
373         thread->debug_ctx = NULL;
374         free( debug_ctx );
375     }
376 }
377
378 /* Wait for a debug event */
379 DECL_HANDLER(wait_debug_event)
380 {
381     if (!wait_for_debug_event( req->timeout ))
382     {
383         req->code = 0;
384         req->pid  = NULL;
385         req->tid  = NULL;
386     }
387 }
388
389 /* Continue a debug event */
390 DECL_HANDLER(continue_debug_event)
391 {
392     struct process *process = get_process_from_id( req->pid );
393     if (process)
394     {
395         struct thread *thread = get_thread_from_id( req->tid );
396         if (thread)
397         {
398             continue_debug_event( process, thread, req->status );
399             release_object( thread );
400         }
401         release_object( process );
402     }
403 }
404
405 /* Start debugging an existing process */
406 DECL_HANDLER(debug_process)
407 {
408     struct process *process = get_process_from_id( req->pid );
409     if (process)
410     {
411         debugger_attach( process, current );
412         /* FIXME: should notice the debugged process somehow */
413         release_object( process );
414     }
415 }
416
417 /* Send a debug event */
418 DECL_HANDLER(send_debug_event)
419 {
420     struct thread *debugger = current->process->debugger;
421
422     assert( !current->debug_event );
423     if ((req->code <= 0) || (req->code > RIP_EVENT))
424     {
425         fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code );
426         return;
427     }
428     req->status = 0;
429     if (debugger && queue_debug_event( debugger, current, req->code, req + 1 ))
430     {
431         /* wait for continue_debug_event */
432         current->state = SLEEPING;
433     }
434 }