Move named pipe objects into directory name space.
[wine] / server / debugger.c
1 /*
2  * Server-side debugger functions
3  *
4  * Copyright (C) 1999 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include "wine/port.h"
23
24 #include <assert.h>
25 #include <signal.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29
30 #include "ntstatus.h"
31 #define WIN32_NO_STATUS
32 #include "windef.h"
33 #include "winternl.h"
34
35 #include "handle.h"
36 #include "process.h"
37 #include "thread.h"
38 #include "request.h"
39 #include "console.h"
40
41 enum debug_event_state { EVENT_QUEUED, EVENT_SENT, EVENT_CONTINUED };
42
43 /* debug event */
44 struct debug_event
45 {
46     struct object          obj;       /* object header */
47     struct list            entry;     /* entry in event queue */
48     struct thread         *sender;    /* thread which sent this event */
49     struct thread         *debugger;  /* debugger thread receiving the event */
50     enum debug_event_state state;     /* event state */
51     int                    status;    /* continuation status */
52     debug_event_t          data;      /* event data */
53     CONTEXT                context;   /* register context */
54 };
55
56 /* debug context */
57 struct debug_ctx
58 {
59     struct object        obj;         /* object header */
60     struct list          event_queue; /* pending events queue */
61     int                  kill_on_exit;/* kill debuggees on debugger exit ? */
62 };
63
64
65 static void debug_event_dump( struct object *obj, int verbose );
66 static int debug_event_signaled( struct object *obj, struct thread *thread );
67 static void debug_event_destroy( struct object *obj );
68
69 static const struct object_ops debug_event_ops =
70 {
71     sizeof(struct debug_event),    /* size */
72     debug_event_dump,              /* dump */
73     add_queue,                     /* add_queue */
74     remove_queue,                  /* remove_queue */
75     debug_event_signaled,          /* signaled */
76     no_satisfied,                  /* satisfied */
77     no_signal,                     /* signal */
78     no_get_fd,                     /* get_fd */
79     no_lookup_name,                /* lookup_name */
80     no_close_handle,               /* close_handle */
81     debug_event_destroy            /* destroy */
82 };
83
84 static void debug_ctx_dump( struct object *obj, int verbose );
85 static int debug_ctx_signaled( struct object *obj, struct thread *thread );
86 static void debug_ctx_destroy( struct object *obj );
87
88 static const struct object_ops debug_ctx_ops =
89 {
90     sizeof(struct debug_ctx),      /* size */
91     debug_ctx_dump,                /* dump */
92     add_queue,                     /* add_queue */
93     remove_queue,                  /* remove_queue */
94     debug_ctx_signaled,            /* signaled */
95     no_satisfied,                  /* satisfied */
96     no_signal,                     /* signal */
97     no_get_fd,                     /* get_fd */
98     no_lookup_name,                /* lookup_name */
99     no_close_handle,               /* close_handle */
100     debug_ctx_destroy              /* destroy */
101 };
102
103
104 /* routines to build an event according to its type */
105
106 static int fill_exception_event( struct debug_event *event, void *arg )
107 {
108     memcpy( &event->data.info.exception, arg, sizeof(event->data.info.exception) );
109     return 1;
110 }
111
112 static int fill_create_thread_event( struct debug_event *event, void *arg )
113 {
114     struct process *debugger = event->debugger->process;
115     struct thread *thread = event->sender;
116     obj_handle_t handle;
117
118     /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
119     if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, FALSE ))) return 0;
120     event->data.info.create_thread.handle = handle;
121     event->data.info.create_thread.teb    = thread->teb;
122     event->data.info.create_thread.start  = arg;
123     return 1;
124 }
125
126 static int fill_create_process_event( struct debug_event *event, void *arg )
127 {
128     struct process *debugger = event->debugger->process;
129     struct thread *thread = event->sender;
130     struct process *process = thread->process;
131     obj_handle_t handle;
132
133     /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
134     if (!(handle = alloc_handle( debugger, process, PROCESS_ALL_ACCESS, FALSE ))) return 0;
135     event->data.info.create_process.process = handle;
136
137     /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
138     if (!(handle = alloc_handle( debugger, thread, THREAD_ALL_ACCESS, FALSE )))
139     {
140         close_handle( debugger, event->data.info.create_process.process, NULL );
141         return 0;
142     }
143     event->data.info.create_process.thread = handle;
144
145     handle = 0;
146     if (process->exe.file &&
147         /* the doc says write access too, but this doesn't seem a good idea */
148         !(handle = alloc_handle( debugger, process->exe.file, GENERIC_READ, FALSE )))
149     {
150         close_handle( debugger, event->data.info.create_process.process, NULL );
151         close_handle( debugger, event->data.info.create_process.thread, NULL );
152         return 0;
153     }
154     event->data.info.create_process.file       = handle;
155     event->data.info.create_process.teb        = thread->teb;
156     event->data.info.create_process.base       = process->exe.base;
157     event->data.info.create_process.start      = arg;
158     event->data.info.create_process.dbg_offset = process->exe.dbg_offset;
159     event->data.info.create_process.dbg_size   = process->exe.dbg_size;
160     event->data.info.create_process.name       = process->exe.name;
161     event->data.info.create_process.unicode    = 1;
162     return 1;
163 }
164
165 static int fill_exit_thread_event( struct debug_event *event, void *arg )
166 {
167     struct thread *thread = arg;
168     event->data.info.exit.exit_code = thread->exit_code;
169     return 1;
170 }
171
172 static int fill_exit_process_event( struct debug_event *event, void *arg )
173 {
174     struct process *process = arg;
175     event->data.info.exit.exit_code = process->exit_code;
176     return 1;
177 }
178
179 static int fill_load_dll_event( struct debug_event *event, void *arg )
180 {
181     struct process *debugger = event->debugger->process;
182     struct process_dll *dll = arg;
183     obj_handle_t handle = 0;
184
185     if (dll->file && !(handle = alloc_handle( debugger, dll->file, GENERIC_READ, FALSE )))
186         return 0;
187     event->data.info.load_dll.handle     = handle;
188     event->data.info.load_dll.base       = dll->base;
189     event->data.info.load_dll.dbg_offset = dll->dbg_offset;
190     event->data.info.load_dll.dbg_size   = dll->dbg_size;
191     event->data.info.load_dll.name       = dll->name;
192     event->data.info.load_dll.unicode    = 1;
193     return 1;
194 }
195
196 static int fill_unload_dll_event( struct debug_event *event, void *arg )
197 {
198     event->data.info.unload_dll.base = arg;
199     return 1;
200 }
201
202 static int fill_output_debug_string_event( struct debug_event *event, void *arg )
203 {
204     struct debug_event_output_string *data = arg;
205     event->data.info.output_string = *data;
206     return 1;
207 }
208
209 typedef int (*fill_event_func)( struct debug_event *event, void *arg );
210
211 #define NB_DEBUG_EVENTS OUTPUT_DEBUG_STRING_EVENT  /* RIP_EVENT not supported */
212
213 static const fill_event_func fill_debug_event[NB_DEBUG_EVENTS] =
214 {
215     fill_exception_event,            /* EXCEPTION_DEBUG_EVENT */
216     fill_create_thread_event,        /* CREATE_THREAD_DEBUG_EVENT */
217     fill_create_process_event,       /* CREATE_PROCESS_DEBUG_EVENT */
218     fill_exit_thread_event,          /* EXIT_THREAD_DEBUG_EVENT */
219     fill_exit_process_event,         /* EXIT_PROCESS_DEBUG_EVENT */
220     fill_load_dll_event,             /* LOAD_DLL_DEBUG_EVENT */
221     fill_unload_dll_event,           /* UNLOAD_DLL_DEBUG_EVENT */
222     fill_output_debug_string_event   /* OUTPUT_DEBUG_STRING_EVENT */
223 };
224
225
226 /* unlink the first event from the queue */
227 static void unlink_event( struct debug_ctx *debug_ctx, struct debug_event *event )
228 {
229     list_remove( &event->entry );
230     if (event->sender->debug_event == event) event->sender->debug_event = NULL;
231     release_object( event );
232 }
233
234 /* link an event at the end of the queue */
235 static void link_event( struct debug_event *event )
236 {
237     struct debug_ctx *debug_ctx = event->debugger->debug_ctx;
238
239     assert( debug_ctx );
240     grab_object( event );
241     list_add_tail( &debug_ctx->event_queue, &event->entry );
242     if (!event->sender->debug_event) wake_up( &debug_ctx->obj, 0 );
243 }
244
245 /* find the next event that we can send to the debugger */
246 static struct debug_event *find_event_to_send( struct debug_ctx *debug_ctx )
247 {
248     struct debug_event *event;
249
250     LIST_FOR_EACH_ENTRY( event, &debug_ctx->event_queue, struct debug_event, entry )
251     {
252         if (event->state == EVENT_SENT) continue;  /* already sent */
253         if (event->sender->debug_event) continue;  /* thread busy with another one */
254         return event;
255     }
256     return NULL;
257 }
258
259 static void debug_event_dump( struct object *obj, int verbose )
260 {
261     struct debug_event *debug_event = (struct debug_event *)obj;
262     assert( obj->ops == &debug_event_ops );
263     fprintf( stderr, "Debug event sender=%p code=%d state=%d\n",
264              debug_event->sender, debug_event->data.code, debug_event->state );
265 }
266
267 static int debug_event_signaled( struct object *obj, struct thread *thread )
268 {
269     struct debug_event *debug_event = (struct debug_event *)obj;
270     assert( obj->ops == &debug_event_ops );
271     return debug_event->state == EVENT_CONTINUED;
272 }
273
274 static void debug_event_destroy( struct object *obj )
275 {
276     struct debug_event *event = (struct debug_event *)obj;
277     assert( obj->ops == &debug_event_ops );
278
279     /* If the event has been sent already, the handles are now under the */
280     /* responsibility of the debugger process, so we don't touch them    */
281     if (event->state == EVENT_QUEUED)
282     {
283         struct process *debugger = event->debugger->process;
284         switch(event->data.code)
285         {
286         case CREATE_THREAD_DEBUG_EVENT:
287             close_handle( debugger, event->data.info.create_thread.handle, NULL );
288             break;
289         case CREATE_PROCESS_DEBUG_EVENT:
290             if (event->data.info.create_process.file)
291                 close_handle( debugger, event->data.info.create_process.file, NULL );
292             close_handle( debugger, event->data.info.create_process.thread, NULL );
293             close_handle( debugger, event->data.info.create_process.process, NULL );
294             break;
295         case LOAD_DLL_DEBUG_EVENT:
296             if (event->data.info.load_dll.handle)
297                 close_handle( debugger, event->data.info.load_dll.handle, NULL );
298             break;
299         }
300     }
301     if (event->sender->context == &event->context) event->sender->context = NULL;
302     release_object( event->sender );
303     release_object( event->debugger );
304 }
305
306 static void debug_ctx_dump( struct object *obj, int verbose )
307 {
308     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
309     assert( obj->ops == &debug_ctx_ops );
310     fprintf( stderr, "Debug context head=%p tail=%p\n",
311              debug_ctx->event_queue.next, debug_ctx->event_queue.prev );
312 }
313
314 static int debug_ctx_signaled( struct object *obj, struct thread *thread )
315 {
316     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
317     assert( obj->ops == &debug_ctx_ops );
318     return find_event_to_send( debug_ctx ) != NULL;
319 }
320
321 static void debug_ctx_destroy( struct object *obj )
322 {
323     struct list *ptr;
324     struct debug_ctx *debug_ctx = (struct debug_ctx *)obj;
325     assert( obj->ops == &debug_ctx_ops );
326
327     /* free all pending events */
328     while ((ptr = list_head( &debug_ctx->event_queue )))
329         unlink_event( debug_ctx, LIST_ENTRY( ptr, struct debug_event, entry ));
330 }
331
332 /* continue a debug event */
333 static int continue_debug_event( struct process *process, struct thread *thread, int status )
334 {
335     struct debug_ctx *debug_ctx = current->debug_ctx;
336
337     if (debug_ctx && process->debugger == current && thread->process == process)
338     {
339         struct debug_event *event;
340
341         /* find the event in the queue */
342         LIST_FOR_EACH_ENTRY( event, &debug_ctx->event_queue, struct debug_event, entry )
343         {
344             if (event->state != EVENT_SENT) continue;
345             if (event->sender == thread)
346             {
347                 assert( event->sender->debug_event == event );
348
349                 event->status = status;
350                 event->state  = EVENT_CONTINUED;
351                 wake_up( &event->obj, 0 );
352                 unlink_event( debug_ctx, event );
353                 resume_process( process );
354                 return 1;
355             }
356         }
357     }
358     /* not debugging this process, or no such event */
359     set_error( STATUS_ACCESS_DENIED );  /* FIXME */
360     return 0;
361 }
362
363 /* alloc a debug event for a debugger */
364 static struct debug_event *alloc_debug_event( struct thread *thread, int code,
365                                               void *arg, const CONTEXT *context )
366 {
367     struct thread *debugger = thread->process->debugger;
368     struct debug_event *event;
369
370     assert( code > 0 && code <= NB_DEBUG_EVENTS );
371     /* cannot queue a debug event for myself */
372     assert( debugger->process != thread->process );
373
374     /* build the event */
375     if (!(event = alloc_object( &debug_event_ops ))) return NULL;
376     event->state     = EVENT_QUEUED;
377     event->sender    = (struct thread *)grab_object( thread );
378     event->debugger  = (struct thread *)grab_object( debugger );
379     event->data.code = code;
380
381     if (!fill_debug_event[code-1]( event, arg ))
382     {
383         event->data.code = -1;  /* make sure we don't attempt to close handles */
384         release_object( event );
385         return NULL;
386     }
387     if (context)
388     {
389         memcpy( &event->context, context, sizeof(event->context) );
390         thread->context = &event->context;
391     }
392     return event;
393 }
394
395 /* generate a debug event from inside the server and queue it */
396 void generate_debug_event( struct thread *thread, int code, void *arg )
397 {
398     if (thread->process->debugger)
399     {
400         struct debug_event *event = alloc_debug_event( thread, code, arg, NULL );
401         if (event)
402         {
403             link_event( event );
404             suspend_process( thread->process );
405             release_object( event );
406         }
407     }
408 }
409
410 /* attach a process to a debugger thread and suspend it */
411 static int debugger_attach( struct process *process, struct thread *debugger )
412 {
413     struct thread *thread;
414
415     if (process->debugger) goto error;  /* already being debugged */
416     if (!is_process_init_done( process )) goto error;  /* still starting up */
417     if (list_empty( &process->thread_list )) goto error;  /* no thread running in the process */
418
419     /* make sure we don't create a debugging loop */
420     for (thread = debugger; thread; thread = thread->process->debugger)
421         if (thread->process == process) goto error;
422
423     /* don't let a debugger debug its console... won't work */
424     if (debugger->process->console && debugger->process->console->renderer->process == process)
425         goto error;
426
427     suspend_process( process );
428     if (!attach_process( process ) || !set_process_debugger( process, debugger ))
429     {
430         resume_process( process );
431         return 0;
432     }
433     if (!set_process_debug_flag( process, 1 ))
434     {
435         process->debugger = NULL;
436         resume_process( process );
437         return 0;
438     }
439     return 1;
440
441  error:
442     set_error( STATUS_ACCESS_DENIED );
443     return 0;
444 }
445
446
447 /* detach a process from a debugger thread (and resume it ?) */
448 int debugger_detach( struct process *process, struct thread *debugger )
449 {
450     struct debug_event *event;
451     struct debug_ctx *debug_ctx;
452
453     if (!process->debugger || process->debugger != debugger)
454         goto error;  /* not currently debugged, or debugged by another debugger */
455     if (!debugger->debug_ctx ) goto error; /* should be a debugger */
456     /* init should be done, otherwise wouldn't be attached */
457     assert(is_process_init_done(process));
458
459     suspend_process( process );
460     /* send continue indication for all events */
461     debug_ctx = debugger->debug_ctx;
462
463     /* find the event in the queue
464      * FIXME: could loop on process' threads and look the debug_event field */
465     LIST_FOR_EACH_ENTRY( event, &debug_ctx->event_queue, struct debug_event, entry )
466     {
467         if (event->state != EVENT_QUEUED) continue;
468
469         if (event->sender->process == process)
470         {
471             assert( event->sender->debug_event == event );
472             event->status = DBG_CONTINUE;
473             event->state  = EVENT_CONTINUED;
474             wake_up( &event->obj, 0 );
475             unlink_event( debug_ctx, event );
476             /* from queued debug event */
477             resume_process( process );
478             break;
479         }
480     }
481
482     /* remove relationships between process and its debugger */
483     process->debugger = NULL;
484     if (!set_process_debug_flag( process, 0 )) clear_error();  /* ignore error */
485     detach_process( process );
486
487     /* from this function */
488     resume_process( process );
489     return 0;
490
491  error:
492     set_error( STATUS_ACCESS_DENIED );
493     return 0;
494 }
495
496 /* generate all startup events of a given process */
497 void generate_startup_debug_events( struct process *process, void *entry )
498 {
499     struct list *ptr;
500     struct thread *thread, *first_thread = get_process_first_thread( process );
501
502     /* generate creation events */
503     LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
504     {
505         if (thread == first_thread)
506             generate_debug_event( thread, CREATE_PROCESS_DEBUG_EVENT, entry );
507         else
508             generate_debug_event( thread, CREATE_THREAD_DEBUG_EVENT, NULL );
509     }
510
511     /* generate dll events (in loading order, i.e. reverse list order) */
512     ptr = list_tail( &process->dlls );
513     while (ptr)
514     {
515         struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
516         generate_debug_event( first_thread, LOAD_DLL_DEBUG_EVENT, dll );
517         ptr = list_prev( &process->dlls, ptr );
518     }
519 }
520
521 /* set the debugger of a given process */
522 int set_process_debugger( struct process *process, struct thread *debugger )
523 {
524     struct debug_ctx *debug_ctx;
525
526     assert( !process->debugger );
527
528     if (!debugger->debug_ctx)  /* need to allocate a context */
529     {
530         if (!(debug_ctx = alloc_object( &debug_ctx_ops ))) return 0;
531         debug_ctx->kill_on_exit = 1;
532         list_init( &debug_ctx->event_queue );
533         debugger->debug_ctx = debug_ctx;
534     }
535     process->debugger = debugger;
536     return 1;
537 }
538
539 /* a thread is exiting */
540 void debug_exit_thread( struct thread *thread )
541 {
542     if (thread->debug_ctx)  /* this thread is a debugger */
543     {
544         if (thread->debug_ctx->kill_on_exit)
545         {
546             /* kill all debugged processes */
547             kill_debugged_processes( thread, thread->exit_code );
548         }
549         else
550         {
551             detach_debugged_processes( thread );
552         }
553         release_object( thread->debug_ctx );
554         thread->debug_ctx = NULL;
555     }
556 }
557
558 /* Wait for a debug event */
559 DECL_HANDLER(wait_debug_event)
560 {
561     struct debug_ctx *debug_ctx = current->debug_ctx;
562     struct debug_event *event;
563
564     if (!debug_ctx)  /* current thread is not a debugger */
565     {
566         set_error( STATUS_INVALID_HANDLE );
567         return;
568     }
569     reply->wait = 0;
570     if ((event = find_event_to_send( debug_ctx )))
571     {
572         size_t size = get_reply_max_size();
573         event->state = EVENT_SENT;
574         event->sender->debug_event = event;
575         reply->pid = get_process_id( event->sender->process );
576         reply->tid = get_thread_id( event->sender );
577         if (size > sizeof(debug_event_t)) size = sizeof(debug_event_t);
578         set_reply_data( &event->data, size );
579     }
580     else  /* no event ready */
581     {
582         reply->pid  = 0;
583         reply->tid  = 0;
584         if (req->get_handle)
585             reply->wait = alloc_handle( current->process, debug_ctx, SYNCHRONIZE, FALSE );
586     }
587 }
588
589 /* Continue a debug event */
590 DECL_HANDLER(continue_debug_event)
591 {
592     struct process *process = get_process_from_id( req->pid );
593     if (process)
594     {
595         struct thread *thread = get_thread_from_id( req->tid );
596         if (thread)
597         {
598             continue_debug_event( process, thread, req->status );
599             release_object( thread );
600         }
601         release_object( process );
602     }
603 }
604
605 /* Start debugging an existing process */
606 DECL_HANDLER(debug_process)
607 {
608     struct process *process = get_process_from_id( req->pid );
609     if (!process) return;
610
611     if (!req->attach)
612     {
613         debugger_detach( process, current );
614     }
615     else if (debugger_attach( process, current ))
616     {
617         struct debug_event_exception data;
618         struct thread *thread = get_process_first_thread( process );
619
620         generate_startup_debug_events( process, NULL );
621         resume_process( process );
622
623         data.record.ExceptionCode    = EXCEPTION_BREAKPOINT;
624         data.record.ExceptionFlags   = EXCEPTION_CONTINUABLE;
625         data.record.ExceptionRecord  = NULL;
626         data.record.ExceptionAddress = get_thread_ip( thread );
627         data.record.NumberParameters = 0;
628         data.first = 1;
629         generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
630     }
631     release_object( process );
632 }
633
634 /* queue an exception event */
635 DECL_HANDLER(queue_exception_event)
636 {
637     reply->handle = 0;
638     if (current->process->debugger)
639     {
640         struct debug_event_exception data;
641         struct debug_event *event;
642         const CONTEXT *context = get_req_data();
643         const EXCEPTION_RECORD *rec = (const EXCEPTION_RECORD *)(context + 1);
644
645         if (get_req_data_size() < sizeof(*rec) + sizeof(*context))
646         {
647             set_error( STATUS_INVALID_PARAMETER );
648             return;
649         }
650         data.record = *rec;
651         data.first  = req->first;
652         if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context )))
653         {
654             if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE )))
655             {
656                 link_event( event );
657                 suspend_process( current->process );
658             }
659             release_object( event );
660         }
661     }
662 }
663
664 /* retrieve the status of an exception event */
665 DECL_HANDLER(get_exception_status)
666 {
667     struct debug_event *event;
668
669     if ((event = (struct debug_event *)get_handle_obj( current->process, req->handle,
670                                                        0, &debug_event_ops )))
671     {
672         close_handle( current->process, req->handle, NULL );
673         if (event->state == EVENT_CONTINUED)
674         {
675             if (current->context == &event->context)
676             {
677                 size_t size = min( sizeof(CONTEXT), get_reply_max_size() );
678                 set_reply_data( &event->context, size );
679                 current->context = NULL;
680             }
681             set_error( event->status );
682         }
683         else set_error( STATUS_PENDING );
684         release_object( event );
685     }
686 }
687
688 /* send an output string to the debugger */
689 DECL_HANDLER(output_debug_string)
690 {
691     struct debug_event_output_string data;
692
693     data.string  = req->string;
694     data.unicode = req->unicode;
695     data.length  = req->length;
696     generate_debug_event( current, OUTPUT_DEBUG_STRING_EVENT, &data );
697 }
698
699 /* simulate a breakpoint in a process */
700 DECL_HANDLER(debug_break)
701 {
702     struct process *process;
703
704     reply->self = 0;
705     if (!(process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION /*FIXME*/ )))
706         return;
707     if (process != current->process)
708     {
709         /* find a suitable thread to signal */
710         struct thread *thread;
711         LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
712         {
713             if (send_thread_signal( thread, SIGTRAP )) goto done;
714         }
715         set_error( STATUS_ACCESS_DENIED );
716     }
717     else reply->self = 1;
718
719 done:
720     release_object( process );
721 }
722
723 /* set debugger kill on exit flag */
724 DECL_HANDLER(set_debugger_kill_on_exit)
725 {
726     if (!current->debug_ctx)
727     {
728         set_error( STATUS_ACCESS_DENIED );
729         return;
730     }
731     current->debug_ctx->kill_on_exit = req->kill_on_exit;
732 }