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