This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / gdb / windows-nat.c
1 /* Target-vector operations for controlling win32 child processes, for GDB.
2    Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions, A Red Hat Company.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21  */
22
23 /* by Steve Chamberlain, sac@cygnus.com */
24
25 /* We assume we're being built with and will be used for cygwin.  */
26
27 #include "defs.h"
28 #include "frame.h"              /* required by inferior.h */
29 #include "inferior.h"
30 #include "target.h"
31 #include "gdbcore.h"
32 #include "command.h"
33 #include <signal.h>
34 #include <sys/types.h>
35 #include <fcntl.h>
36 #include <stdlib.h>
37 #include <windows.h>
38 #include <imagehlp.h>
39 #include <sys/cygwin.h>
40
41 #include "buildsym.h"
42 #include "symfile.h"
43 #include "objfiles.h"
44 #include "gdb_string.h"
45 #include "gdbthread.h"
46 #include "gdbcmd.h"
47 #include <sys/param.h>
48 #include <unistd.h>
49
50 /* The ui's event loop. */
51 extern int (*ui_loop_hook) (int signo);
52
53 /* If we're not using the old Cygwin header file set, define the
54    following which never should have been in the generic Win32 API
55    headers in the first place since they were our own invention... */
56 #ifndef _GNU_H_WINDOWS_H
57 #define FLAG_TRACE_BIT 0x100
58 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
59 #endif
60
61 /* The string sent by cygwin when it processes a signal.
62    FIXME: This should be in a cygwin include file. */
63 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
64
65 #define CHECK(x)        check (x, __FILE__,__LINE__)
66 #define DEBUG_EXEC(x)   if (debug_exec)         printf x
67 #define DEBUG_EVENTS(x) if (debug_events)       printf x
68 #define DEBUG_MEM(x)    if (debug_memory)       printf x
69 #define DEBUG_EXCEPT(x) if (debug_exceptions)   printf x
70
71 /* Forward declaration */
72 extern struct target_ops child_ops;
73
74 static void child_stop (void);
75 static int win32_child_thread_alive (int);
76 void child_kill_inferior (void);
77
78 static int last_sig = 0;        /* Set if a signal was received from the
79                                    debugged process */
80 /* Thread information structure used to track information that is
81    not available in gdb's thread structure. */
82 typedef struct thread_info_struct
83   {
84     struct thread_info_struct *next;
85     DWORD id;
86     HANDLE h;
87     char *name;
88     int suspend_count;
89     CONTEXT context;
90     STACKFRAME sf;
91   } thread_info;
92
93 static thread_info thread_head;
94
95 /* The process and thread handles for the above context. */
96
97 static DEBUG_EVENT current_event;       /* The current debug event from
98                                            WaitForDebugEvent */
99 static HANDLE current_process_handle;   /* Currently executing process */
100 static thread_info *current_thread;     /* Info on currently selected thread */
101 static DWORD main_thread_id;    /* Thread ID of the main thread */
102
103 /* Counts of things. */
104 static int exception_count = 0;
105 static int event_count = 0;
106
107 /* User options. */
108 static int new_console = 0;
109 static int new_group = 1;
110 static int debug_exec = 0;      /* show execution */
111 static int debug_events = 0;    /* show events from kernel */
112 static int debug_memory = 0;    /* show target memory accesses */
113 static int debug_exceptions = 0;        /* show target exceptions */
114
115 /* This vector maps GDB's idea of a register's number into an address
116    in the win32 exception context vector.
117
118    It also contains the bit mask needed to load the register in question.
119
120    One day we could read a reg, we could inspect the context we
121    already have loaded, if it doesn't have the bit set that we need,
122    we read that set of registers in using GetThreadContext.  If the
123    context already contains what we need, we just unpack it. Then to
124    write a register, first we have to ensure that the context contains
125    the other regs of the group, and then we copy the info in and set
126    out bit. */
127
128 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
129 static const int mappings[] =
130 {
131   context_offset (Eax),
132   context_offset (Ecx),
133   context_offset (Edx),
134   context_offset (Ebx),
135   context_offset (Esp),
136   context_offset (Ebp),
137   context_offset (Esi),
138   context_offset (Edi),
139   context_offset (Eip),
140   context_offset (EFlags),
141   context_offset (SegCs),
142   context_offset (SegSs),
143   context_offset (SegDs),
144   context_offset (SegEs),
145   context_offset (SegFs),
146   context_offset (SegGs),
147   context_offset (FloatSave.RegisterArea[0 * 10]),
148   context_offset (FloatSave.RegisterArea[1 * 10]),
149   context_offset (FloatSave.RegisterArea[2 * 10]),
150   context_offset (FloatSave.RegisterArea[3 * 10]),
151   context_offset (FloatSave.RegisterArea[4 * 10]),
152   context_offset (FloatSave.RegisterArea[5 * 10]),
153   context_offset (FloatSave.RegisterArea[6 * 10]),
154   context_offset (FloatSave.RegisterArea[7 * 10]),
155   context_offset (FloatSave.ControlWord),
156   context_offset (FloatSave.StatusWord),
157   context_offset (FloatSave.TagWord),
158   context_offset (FloatSave.ErrorSelector),
159   context_offset (FloatSave.ErrorOffset),
160   context_offset (FloatSave.DataSelector),
161   context_offset (FloatSave.DataOffset),
162   context_offset (FloatSave.ErrorSelector)
163 };
164
165 #undef context_offset
166
167 /* This vector maps the target's idea of an exception (extracted
168    from the DEBUG_EVENT structure) to GDB's idea. */
169
170 struct xlate_exception
171   {
172     int them;
173     enum target_signal us;
174   };
175
176 static const struct xlate_exception
177   xlate[] =
178 {
179   {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
180   {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
181   {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
182   {DBG_CONTROL_C, TARGET_SIGNAL_INT},
183   {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
184   {-1, -1}};
185
186 /* Find a thread record given a thread id.
187    If get_context then also retrieve the context for this
188    thread. */
189 static thread_info *
190 thread_rec (DWORD id, int get_context)
191 {
192   thread_info *th;
193
194   for (th = &thread_head; (th = th->next) != NULL;)
195     if (th->id == id)
196       {
197         if (!th->suspend_count && get_context)
198           {
199             if (get_context > 0 && id != current_event.dwThreadId)
200               th->suspend_count = SuspendThread (th->h) + 1;
201             else if (get_context < 0)
202               th->suspend_count = -1;
203
204             th->context.ContextFlags = CONTEXT_DEBUGGER;
205             GetThreadContext (th->h, &th->context);
206           }
207         return th;
208       }
209
210   return NULL;
211 }
212
213 /* Add a thread to the thread list */
214 static thread_info *
215 child_add_thread (DWORD id, HANDLE h)
216 {
217   thread_info *th;
218
219   if ((th = thread_rec (id, FALSE)))
220     return th;
221
222   th = (thread_info *) xmalloc (sizeof (*th));
223   memset (th, 0, sizeof (*th));
224   th->id = id;
225   th->h = h;
226   th->next = thread_head.next;
227   thread_head.next = th;
228   add_thread (id);
229   return th;
230 }
231
232 /* Clear out any old thread list and reintialize it to a
233    pristine state. */
234 static void
235 child_init_thread_list ()
236 {
237   thread_info *th = &thread_head;
238
239   DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
240   init_thread_list ();
241   while (th->next != NULL)
242     {
243       thread_info *here = th->next;
244       th->next = here->next;
245       (void) CloseHandle (here->h);
246       free (here);
247     }
248 }
249
250 /* Delete a thread from the list of threads */
251 static void
252 child_delete_thread (DWORD id)
253 {
254   thread_info *th;
255
256   if (info_verbose)
257     printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
258   delete_thread (id);
259
260   for (th = &thread_head;
261        th->next != NULL && th->next->id != id;
262        th = th->next)
263     continue;
264
265   if (th->next != NULL)
266     {
267       thread_info *here = th->next;
268       th->next = here->next;
269       CloseHandle (here->h);
270       free (here);
271     }
272 }
273
274 static void
275 check (BOOL ok, const char *file, int line)
276 {
277   if (!ok)
278     printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
279 }
280
281 static void
282 do_child_fetch_inferior_registers (int r)
283 {
284   char *context_offset = ((char *) &current_thread->context) + mappings[r];
285   long l;
286   if (r == FCS_REGNUM)
287     {
288       l = *((long *)context_offset) & 0xffff;
289       supply_register (r, (char *) &l);
290     }
291   else if (r == FOP_REGNUM)
292     {
293       l = (*((long *)context_offset) >> 16) & ((1 << 11) - 1);
294       supply_register (r, (char *) &l);
295     }
296   else if (r >= 0)
297     supply_register (r, context_offset);
298   else
299     {
300       for (r = 0; r < NUM_REGS; r++)
301         do_child_fetch_inferior_registers (r);
302     }
303 }
304
305 static void
306 child_fetch_inferior_registers (int r)
307 {
308   current_thread = thread_rec (inferior_pid, TRUE);
309   do_child_fetch_inferior_registers (r);
310 }
311
312 static void
313 do_child_store_inferior_registers (int r)
314 {
315   if (r >= 0)
316     read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
317   else
318     {
319       for (r = 0; r < NUM_REGS; r++)
320         do_child_store_inferior_registers (r);
321     }
322 }
323
324 /* Store a new register value into the current thread context */
325 static void
326 child_store_inferior_registers (int r)
327 {
328   current_thread = thread_rec (inferior_pid, TRUE);
329   do_child_store_inferior_registers (r);
330 }
331
332 #include <psapi.h>
333 static int psapi_loaded = 0;
334 static HMODULE psapi_module_handle = NULL;
335 static BOOL  WINAPI (*psapi_EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD)= NULL;
336 static BOOL  WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD)= NULL;
337 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD)= NULL;
338
339 int psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
340 {
341   DWORD len;
342   MODULEINFO mi;
343   int i;
344   HMODULE dh_buf [ 1 ];
345   HMODULE* DllHandle = dh_buf;
346   DWORD cbNeeded;
347   BOOL ok;
348
349   if (!psapi_loaded ||
350        psapi_EnumProcessModules   == NULL ||
351        psapi_GetModuleInformation == NULL ||
352        psapi_GetModuleFileNameExA == NULL)
353     {
354       if (psapi_loaded)goto failed;
355       psapi_loaded = 1;
356       psapi_module_handle = LoadLibrary ("psapi.dll");
357       if (!psapi_module_handle)
358         {
359           /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
360           goto failed;
361         }
362       psapi_EnumProcessModules   = GetProcAddress (psapi_module_handle, "EnumProcessModules" );
363       psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
364       psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
365                                                             "GetModuleFileNameExA");
366       if (psapi_EnumProcessModules   == NULL ||
367            psapi_GetModuleInformation == NULL ||
368            psapi_GetModuleFileNameExA == NULL)
369         goto failed;
370     }
371
372   cbNeeded = 0;
373   ok = (*psapi_EnumProcessModules) (current_process_handle,
374                                      DllHandle,
375                                      sizeof (HMODULE),
376                                      &cbNeeded);
377
378   if (!ok || !cbNeeded)
379     goto failed;
380
381   DllHandle = (HMODULE*) alloca (cbNeeded);
382   if (!DllHandle)
383     goto failed;
384
385   ok = (*psapi_EnumProcessModules) (current_process_handle,
386                                      DllHandle,
387                                      cbNeeded,
388                                      &cbNeeded);
389   if (!ok)
390     goto failed;
391
392   for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
393     {
394       if (!(*psapi_GetModuleInformation) (current_process_handle,
395                                              DllHandle [i],
396                                              &mi,
397                                              sizeof (mi)))
398         error ("Can't get module info");
399
400       len = (*psapi_GetModuleFileNameExA) (current_process_handle,
401                                             DllHandle [i],
402                                             dll_name_ret,
403                                             MAX_PATH);
404       if (len == 0)
405         error ("Error getting dll name: %u\n", GetLastError ());
406
407       if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
408         return 1;
409     }
410
411 failed:
412   dll_name_ret[0] = '\0';
413   return 0;
414 }
415
416 /* Encapsulate the information required in a call to
417    symbol_file_add_args */
418 struct safe_symbol_file_add_args
419 {
420   char *name;
421   int from_tty;
422   struct section_addr_info *addrs;
423   int mainline;
424   int flags;
425   struct ui_file *err, *out;
426   struct objfile *ret;
427 };
428
429 /* Call symbol_file_add with stderr redirected.  We don't care if there
430    are errors. */
431 static int
432 safe_symbol_file_add_stub (void *argv)
433 {
434 #define p ((struct safe_symbol_file_add_args *)argv)
435   p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
436   return !!p->ret;
437 #undef p
438 }
439
440 /* Restore gdb's stderr after calling symbol_file_add */
441 static void
442 safe_symbol_file_add_cleanup (void *p)
443 {
444 #define sp ((struct safe_symbol_file_add_args *)p)
445   gdb_flush (gdb_stderr);
446   gdb_flush (gdb_stdout);
447   ui_file_delete (gdb_stderr);
448   ui_file_delete (gdb_stdout);
449   gdb_stderr = sp->err;
450   gdb_stdout = sp->err;
451 }
452
453 /* symbol_file_add wrapper that prevents errors from being displayed. */
454 static struct objfile *
455 safe_symbol_file_add (char *name, int from_tty,
456                       struct section_addr_info *addrs,
457                       int mainline, int flags)
458
459 {
460   struct safe_symbol_file_add_args p;
461   struct cleanup *cleanup;
462
463   cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
464
465   p.err = gdb_stderr;
466   p.out = gdb_stdout;
467   gdb_flush (gdb_stderr);
468   gdb_flush (gdb_stdout);
469   gdb_stderr = ui_file_new ();
470   gdb_stdout = ui_file_new ();
471   p.name = name;
472   p.from_tty = from_tty;
473   p.addrs = addrs;
474   p.mainline = mainline;
475   p.flags = flags;
476   catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
477
478   do_cleanups (cleanup);
479   return p.ret;
480 }
481
482 /* Maintain a linked list of "so" information. */
483 struct so_stuff
484 {
485   struct so_stuff *next, **last;
486   DWORD load_addr;
487   char name[0];
488 } solib_start, *solib_end;
489
490 /* Remember the maximum DLL length for printing in info dll command. */
491 int max_dll_name_len;
492
493 /* Wait for child to do something.  Return pid of child, or -1 in case
494    of error; store status through argument pointer OURSTATUS.  */
495 static int
496 handle_load_dll (PTR dummy ATTRIBUTE_UNUSED)
497 {
498   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
499   DWORD dll_name_ptr;
500   DWORD done;
501   char dll_buf[MAX_PATH + 1];
502   struct so_stuff *so, *solast;
503   char *dll_name = NULL;
504   DWORD dll_base = 0;
505   int len;
506   char *p;
507
508   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
509
510   if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
511     dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
512
513   dll_name = dll_buf;
514
515   /* Attempt to read the name of the dll that was detected.
516      This is documented to work only when actively debugging
517      a program.  It will not work for attached processes. */
518   if (dll_name == NULL || *dll_name == '\0')
519     {
520       DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
521       int len = 0;
522       char b[2];
523
524       ReadProcessMemory (current_process_handle,
525                          (LPCVOID) event->lpImageName,
526                          (char *) &dll_name_ptr,
527                          sizeof (dll_name_ptr), &done);
528
529       /* See if we could read the address of a string, and that the
530          address isn't null. */
531
532       if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
533         return 1;
534
535       do
536         {
537           ReadProcessMemory (current_process_handle,
538                              (LPCVOID) (dll_name_ptr + len * size),
539                              &b,
540                              size,
541                              &done);
542           len++;
543         }
544       while ((b[0] != 0 || b[size - 1] != 0) && done == size);
545
546       dll_name = alloca (len);
547
548       if (event->fUnicode)
549         {
550           WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
551           ReadProcessMemory (current_process_handle,
552                              (LPCVOID) dll_name_ptr,
553                              unicode_dll_name,
554                              len * sizeof (WCHAR),
555                              &done);
556
557           WideCharToMultiByte (CP_ACP, 0,
558                                unicode_dll_name, len,
559                                dll_name, len, 0, 0);
560         }
561       else
562         {
563           ReadProcessMemory (current_process_handle,
564                              (LPCVOID) dll_name_ptr,
565                              dll_name,
566                              len,
567                              &done);
568         }
569     }
570
571   if (!dll_name)
572     return 1;
573
574   (void) strlwr (dll_name);
575
576   while ((p = strchr (dll_name, '\\')))
577     *p = '/';
578
579   so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) +  strlen (dll_name) + 8 + 2);
580   so->load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
581   strcpy (so->name, dll_name);
582
583   solib_end->next = so;
584   solib_end = so;
585   so->next = NULL;
586
587   len = strlen (dll_name);
588   if (len > max_dll_name_len)
589     max_dll_name_len = len;
590
591   return 1;
592 }
593
594 /* Return name of last loaded DLL. */
595 char *
596 child_solib_loaded_library_pathname (int pid)
597 {
598   return !solib_end || !solib_end->name[0]? NULL : solib_end->name;
599 }
600
601 /* Clear list of loaded DLLs. */
602 void
603 child_clear_solibs (void)
604 {
605   struct so_stuff *so, *so1 = solib_start.next;
606
607   while ((so = so1) != NULL)
608     {
609       so1 = so->next;
610       free (so);
611     }
612
613   solib_start.next = NULL;
614   solib_end = &solib_start;
615   max_dll_name_len = sizeof ("DLL Name") - 1;
616 }
617
618 /* Add DLL symbol information. */
619 void
620 child_solib_add (char *filename, int from_tty, struct target_ops *t)
621 {
622   struct section_addr_info section_addrs;
623
624   /* The symbols in a dll are offset by 0x1000, which is the
625      the offset from 0 of the first byte in an image - because
626      of the file header and the section alignment. */
627
628   if (!solib_end || !solib_end->name[0])
629     return;
630
631   memset (&section_addrs, 0, sizeof (section_addrs));
632   section_addrs.other[0].name = ".text";
633   section_addrs.other[0].addr = solib_end->load_addr;
634   safe_symbol_file_add (solib_end->name, 0, &section_addrs, 0, OBJF_SHARED);
635
636   return;
637 }
638
639 /* Load DLL symbol info. */
640 void
641 dll_symbol_command (char *args, int from_tty)
642 {
643   struct section_addr_info section_addrs;
644
645   dont_repeat ();
646   
647   if (args == NULL)
648     error ("dll-symbols requires a file name");
649
650   safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED);
651
652
653 /* List currently loaded DLLs. */
654 void
655 info_dll_command (char *ignore, int from_tty)
656 {
657   struct so_stuff *so = &solib_start;
658
659   if (!so->next)
660     return;
661
662   printf ("%*s  Load Address\n", -max_dll_name_len, "DLL Name");
663   while ((so = so->next) != NULL)
664     printf_filtered ("%*s  %08lx\n", -max_dll_name_len, so->name, so->load_addr);
665
666   return;
667 }
668
669 /* Handle DEBUG_STRING output from child process.
670    Cygwin prepends its messages with a "cygwin:".  Interpret this as
671    a Cygwin signal.  Otherwise just print the string as a warning. */
672 static int
673 handle_output_debug_string (struct target_waitstatus *ourstatus)
674 {
675   char *s;
676   int gotasig = FALSE;
677
678   if (!target_read_string
679     ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
680       || !s || !*s)
681     return gotasig;
682
683   if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
684     {
685       if (strncmp (s, "cYg", 3) != 0)
686         warning ("%s", s);
687     }
688   else
689     {
690       char *p;
691       int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
692       gotasig = target_signal_from_host (sig);
693       ourstatus->value.sig = gotasig;
694       if (gotasig)
695         ourstatus->kind = TARGET_WAITKIND_STOPPED;
696     }
697
698   free (s);
699   return gotasig;
700 }
701
702 static int
703 handle_exception (struct target_waitstatus *ourstatus)
704 {
705   thread_info *th;
706   DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
707
708   ourstatus->kind = TARGET_WAITKIND_STOPPED;
709
710   /* Record the context of the current thread */
711   th = thread_rec (current_event.dwThreadId, -1);
712
713   last_sig = 0;
714
715   switch (code)
716     {
717     case EXCEPTION_ACCESS_VIOLATION:
718       DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
719                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
720       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
721       last_sig = SIGSEGV;
722       break;
723     case STATUS_FLOAT_UNDERFLOW:
724     case STATUS_FLOAT_DIVIDE_BY_ZERO:
725     case STATUS_FLOAT_OVERFLOW:
726     case STATUS_INTEGER_DIVIDE_BY_ZERO:
727       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
728                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
729       ourstatus->value.sig = TARGET_SIGNAL_FPE;
730       last_sig = SIGFPE;
731       break;
732     case STATUS_STACK_OVERFLOW:
733       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
734                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
735       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
736       break;
737     case EXCEPTION_BREAKPOINT:
738       DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
739                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
740       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
741       break;
742     case DBG_CONTROL_C:
743       DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
744                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
745       ourstatus->value.sig = TARGET_SIGNAL_INT;
746       last_sig = SIGINT;        /* FIXME - should check pass state */
747       break;
748     case EXCEPTION_SINGLE_STEP:
749       DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
750                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
751       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
752       break;
753     case EXCEPTION_ILLEGAL_INSTRUCTION:
754       DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
755                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
756       ourstatus->value.sig = TARGET_SIGNAL_ILL;
757       last_sig = SIGILL;
758       break;
759     default:
760       printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
761                     current_event.u.Exception.ExceptionRecord.ExceptionCode,
762                 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
763       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
764       break;
765     }
766   exception_count++;
767   return 1;
768 }
769
770 /* Resume all artificially suspended threads if we are continuing
771    execution */
772 static BOOL
773 child_continue (DWORD continue_status, int id)
774 {
775   int i;
776   thread_info *th;
777   BOOL res;
778
779   DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
780                  current_event.dwProcessId, current_event.dwThreadId));
781   res = ContinueDebugEvent (current_event.dwProcessId,
782                             current_event.dwThreadId,
783                             continue_status);
784   continue_status = 0;
785   if (res)
786     for (th = &thread_head; (th = th->next) != NULL;)
787       if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
788         {
789           for (i = 0; i < th->suspend_count; i++)
790             (void) ResumeThread (th->h);
791           th->suspend_count = 0;
792         }
793
794   return res;
795 }
796
797 /* Get the next event from the child.  Return 1 if the event requires
798    handling by WFI (or whatever).
799  */
800 static int
801 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
802 {
803   int breakout = 0;
804   BOOL debug_event;
805   DWORD continue_status, event_code;
806   thread_info *th = NULL;
807   static thread_info dummy_thread_info;
808   int retval = 0;
809
810   if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
811     goto out;
812
813   event_count++;
814   continue_status = DBG_CONTINUE;
815
816   event_code = current_event.dwDebugEventCode;
817   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
818
819   switch (event_code)
820     {
821     case CREATE_THREAD_DEBUG_EVENT:
822       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
823                      (unsigned) current_event.dwProcessId,
824                      (unsigned) current_event.dwThreadId,
825                      "CREATE_THREAD_DEBUG_EVENT"));
826       /* Record the existence of this thread */
827       th = child_add_thread (current_event.dwThreadId,
828                              current_event.u.CreateThread.hThread);
829       if (info_verbose)
830         printf_unfiltered ("[New %s]\n",
831                            target_pid_to_str (current_event.dwThreadId));
832       retval = current_event.dwThreadId;
833       break;
834
835     case EXIT_THREAD_DEBUG_EVENT:
836       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
837                      (unsigned) current_event.dwProcessId,
838                      (unsigned) current_event.dwThreadId,
839                      "EXIT_THREAD_DEBUG_EVENT"));
840       child_delete_thread (current_event.dwThreadId);
841       th = &dummy_thread_info;
842       break;
843
844     case CREATE_PROCESS_DEBUG_EVENT:
845       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
846                      (unsigned) current_event.dwProcessId,
847                      (unsigned) current_event.dwThreadId,
848                      "CREATE_PROCESS_DEBUG_EVENT"));
849       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
850
851       main_thread_id = inferior_pid = current_event.dwThreadId;
852       /* Add the main thread */
853       th = child_add_thread (current_event.dwProcessId,
854                              current_event.u.CreateProcessInfo.hProcess);
855       th = child_add_thread (inferior_pid,
856                              current_event.u.CreateProcessInfo.hThread);
857       retval = ourstatus->value.related_pid = current_event.dwProcessId;
858       break;
859
860     case EXIT_PROCESS_DEBUG_EVENT:
861       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
862                      (unsigned) current_event.dwProcessId,
863                      (unsigned) current_event.dwThreadId,
864                      "EXIT_PROCESS_DEBUG_EVENT"));
865       ourstatus->kind = TARGET_WAITKIND_EXITED;
866       ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
867       CloseHandle (current_process_handle);
868       retval = current_event.dwProcessId;
869       break;
870
871     case LOAD_DLL_DEBUG_EVENT:
872       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
873                      (unsigned) current_event.dwProcessId,
874                      (unsigned) current_event.dwThreadId,
875                      "LOAD_DLL_DEBUG_EVENT"));
876       catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
877       registers_changed ();     /* mark all regs invalid */
878       ourstatus->kind = TARGET_WAITKIND_LOADED;
879       ourstatus->value.integer = 0;
880       retval = current_event.dwProcessId;
881       break;
882
883     case UNLOAD_DLL_DEBUG_EVENT:
884       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
885                      (unsigned) current_event.dwProcessId,
886                      (unsigned) current_event.dwThreadId,
887                      "UNLOAD_DLL_DEBUG_EVENT"));
888       break;                    /* FIXME: don't know what to do here */
889
890     case EXCEPTION_DEBUG_EVENT:
891       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
892                      (unsigned) current_event.dwProcessId,
893                      (unsigned) current_event.dwThreadId,
894                      "EXCEPTION_DEBUG_EVENT"));
895       handle_exception (ourstatus);
896       retval = current_event.dwThreadId;
897       break;
898
899     case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
900       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
901                      (unsigned) current_event.dwProcessId,
902                      (unsigned) current_event.dwThreadId,
903                      "OUTPUT_DEBUG_STRING_EVENT"));
904       if (handle_output_debug_string ( ourstatus))
905         retval = current_event.dwProcessId;
906       break;
907     default:
908       printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
909                          (DWORD) current_event.dwProcessId,
910                          (DWORD) current_event.dwThreadId);
911       printf_unfiltered ("                 unknown event code %ld\n",
912                          current_event.dwDebugEventCode);
913       break;
914     }
915
916   if (!retval)
917     CHECK (child_continue (continue_status, -1));
918   else
919     current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
920
921 out:
922   return retval;
923 }
924
925 /* Wait for interesting events to occur in the target process. */
926 static int
927 child_wait (int pid, struct target_waitstatus *ourstatus)
928 {
929   /* We loop when we get a non-standard exception rather than return
930      with a SPURIOUS because resume can try and step or modify things,
931      which needs a current_thread->h.  But some of these exceptions mark
932      the birth or death of threads, which mean that the current thread
933      isn't necessarily what you think it is. */
934
935   while (1)
936     {
937       int retval = get_child_debug_event (pid, ourstatus);
938       if (retval)
939         return retval;
940       else
941         {
942           int detach = 0;
943
944           if (ui_loop_hook != NULL)
945             detach = ui_loop_hook (0);
946
947           if (detach)
948             child_kill_inferior ();
949         }
950     }
951 }
952
953 /* Attach to process PID, then initialize for debugging it.  */
954
955 static void
956 child_attach (args, from_tty)
957      char *args;
958      int from_tty;
959 {
960   BOOL ok;
961
962   if (!args)
963     error_no_arg ("process-id to attach");
964
965   current_event.dwProcessId = strtoul (args, 0, 0);
966
967   ok = DebugActiveProcess (current_event.dwProcessId);
968
969   if (!ok)
970     error ("Can't attach to process.");
971
972   exception_count = 0;
973   event_count = 0;
974
975   child_init_thread_list ();
976   child_clear_solibs ();
977
978   if (from_tty)
979     {
980       char *exec_file = (char *) get_exec_file (0);
981
982       if (exec_file)
983         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
984                            target_pid_to_str (current_event.dwProcessId));
985       else
986         printf_unfiltered ("Attaching to %s\n",
987                            target_pid_to_str (current_event.dwProcessId));
988
989       gdb_flush (gdb_stdout);
990     }
991
992   push_target (&child_ops);
993 }
994
995 static void
996 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
997 {
998   if (from_tty)
999     {
1000       char *exec_file = get_exec_file (0);
1001       if (exec_file == 0)
1002         exec_file = "";
1003       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
1004                          target_pid_to_str (inferior_pid));
1005       gdb_flush (gdb_stdout);
1006     }
1007   inferior_pid = 0;
1008   unpush_target (&child_ops);
1009 }
1010
1011 /* Print status information about what we're accessing.  */
1012
1013 static void
1014 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1015 {
1016   printf_unfiltered ("\tUsing the running image of %s %s.\n",
1017       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
1018 }
1019
1020 /* ARGSUSED */
1021 static void
1022 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1023 {
1024   error ("Use the \"run\" command to start a Unix child process.");
1025 }
1026
1027 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1028    EXEC_FILE is the file to run.
1029    ALLARGS is a string containing the arguments to the program.
1030    ENV is the environment vector to pass.  Errors reported with error().  */
1031
1032 static void
1033 child_create_inferior (exec_file, allargs, env)
1034      char *exec_file;
1035      char *allargs;
1036      char **env;
1037 {
1038   char real_path[MAXPATHLEN];
1039   char *winenv;
1040   char *temp;
1041   int envlen;
1042   int i;
1043   STARTUPINFO si;
1044   PROCESS_INFORMATION pi;
1045   struct target_waitstatus dummy;
1046   BOOL ret;
1047   DWORD flags;
1048   char *args;
1049   extern int stop_after_trap;
1050
1051   if (!exec_file)
1052     error ("No executable specified, use `target exec'.\n");
1053
1054   memset (&si, 0, sizeof (si));
1055   si.cb = sizeof (si);
1056
1057   cygwin_conv_to_win32_path (exec_file, real_path);
1058
1059   flags = DEBUG_ONLY_THIS_PROCESS;
1060
1061   if (new_group)
1062     flags |= CREATE_NEW_PROCESS_GROUP;
1063
1064   if (new_console)
1065     flags |= CREATE_NEW_CONSOLE;
1066
1067   args = alloca (strlen (real_path) + strlen (allargs) + 2);
1068
1069   strcpy (args, real_path);
1070
1071   strcat (args, " ");
1072   strcat (args, allargs);
1073
1074   /* Prepare the environment vars for CreateProcess.  */
1075   {
1076     /* This code use to assume all env vars were file names and would
1077        translate them all to win32 style.  That obviously doesn't work in the
1078        general case.  The current rule is that we only translate PATH.
1079        We need to handle PATH because we're about to call CreateProcess and
1080        it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1081        in both posix and win32 environments.  cygwin.dll will change it back
1082        to posix style if necessary.  */
1083
1084     static const char *conv_path_names[] =
1085     {
1086       "PATH=",
1087       0
1088     };
1089
1090     /* CreateProcess takes the environment list as a null terminated set of
1091        strings (i.e. two nulls terminate the list).  */
1092
1093     /* Get total size for env strings.  */
1094     for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1095       {
1096         int j, len;
1097
1098         for (j = 0; conv_path_names[j]; j++)
1099           {
1100             len = strlen (conv_path_names[j]);
1101             if (strncmp (conv_path_names[j], env[i], len) == 0)
1102               {
1103                 if (cygwin_posix_path_list_p (env[i] + len))
1104                   envlen += len
1105                     + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1106                 else
1107                   envlen += strlen (env[i]) + 1;
1108                 break;
1109               }
1110           }
1111         if (conv_path_names[j] == NULL)
1112           envlen += strlen (env[i]) + 1;
1113       }
1114
1115     winenv = alloca (envlen + 1);
1116
1117     /* Copy env strings into new buffer.  */
1118     for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1119       {
1120         int j, len;
1121
1122         for (j = 0; conv_path_names[j]; j++)
1123           {
1124             len = strlen (conv_path_names[j]);
1125             if (strncmp (conv_path_names[j], env[i], len) == 0)
1126               {
1127                 if (cygwin_posix_path_list_p (env[i] + len))
1128                   {
1129                     memcpy (temp, env[i], len);
1130                     cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1131                   }
1132                 else
1133                   strcpy (temp, env[i]);
1134                 break;
1135               }
1136           }
1137         if (conv_path_names[j] == NULL)
1138           strcpy (temp, env[i]);
1139
1140         temp += strlen (temp) + 1;
1141       }
1142
1143     /* Final nil string to terminate new env.  */
1144     *temp = 0;
1145   }
1146
1147   ret = CreateProcess (0,
1148                        args,    /* command line */
1149                        NULL,    /* Security */
1150                        NULL,    /* thread */
1151                        TRUE,    /* inherit handles */
1152                        flags,   /* start flags */
1153                        winenv,
1154                        NULL,    /* current directory */
1155                        &si,
1156                        &pi);
1157   if (!ret)
1158     error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1159
1160   exception_count = 0;
1161   event_count = 0;
1162
1163   current_process_handle = pi.hProcess;
1164   current_event.dwProcessId = pi.dwProcessId;
1165   memset (&current_event, 0, sizeof (current_event));
1166   inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1167   push_target (&child_ops);
1168   child_init_thread_list ();
1169   child_clear_solibs ();
1170   clear_proceed_status ();
1171   init_wait_for_inferior ();
1172   target_terminal_init ();
1173   target_terminal_inferior ();
1174   last_sig = 0;
1175
1176   while (1)
1177     {
1178       stop_after_trap = 1;
1179       wait_for_inferior ();
1180       if (stop_signal != TARGET_SIGNAL_TRAP)
1181         resume (0, stop_signal);
1182       else
1183         break;
1184     }
1185   stop_after_trap = 0;
1186
1187   /* child_continue (DBG_CONTINUE, -1);*/
1188   proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1189 }
1190
1191 static void
1192 child_mourn_inferior ()
1193 {
1194   (void) child_continue (DBG_CONTINUE, -1);
1195   unpush_target (&child_ops);
1196   generic_mourn_inferior ();
1197 }
1198
1199 /* Send a SIGINT to the process group.  This acts just like the user typed a
1200    ^C on the controlling terminal. */
1201
1202 static void
1203 child_stop ()
1204 {
1205   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1206   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1207   registers_changed ();         /* refresh register state */
1208 }
1209
1210 int
1211 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1212                    int write, struct target_ops *target ATTRIBUTE_UNUSED)
1213 {
1214   DWORD done;
1215   if (write)
1216     {
1217       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1218                   len, (DWORD) memaddr));
1219       WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1220                           len, &done);
1221       FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1222     }
1223   else
1224     {
1225       DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1226                   len, (DWORD) memaddr));
1227       ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1228                          &done);
1229     }
1230   return done;
1231 }
1232
1233 void
1234 child_kill_inferior (void)
1235 {
1236   CHECK (TerminateProcess (current_process_handle, 0));
1237
1238   for (;;)
1239     {
1240       if (!child_continue (DBG_CONTINUE, -1))
1241         break;
1242       if (!WaitForDebugEvent (&current_event, INFINITE))
1243         break;
1244       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1245         break;
1246     }
1247
1248   CHECK (CloseHandle (current_process_handle));
1249
1250   /* this may fail in an attached process so don't check. */
1251   (void) CloseHandle (current_thread->h);
1252   target_mourn_inferior ();     /* or just child_mourn_inferior? */
1253 }
1254
1255 void
1256 child_resume (int pid, int step, enum target_signal sig)
1257 {
1258   thread_info *th;
1259   DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1260                           DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1261
1262   last_sig = 0;
1263
1264   DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1265                pid, step, sig));
1266
1267   /* Get context for currently selected thread */
1268   th = thread_rec (current_event.dwThreadId, FALSE);
1269   if (th)
1270     {
1271       if (step)
1272         {
1273           /* Single step by setting t bit */
1274           child_fetch_inferior_registers (PS_REGNUM);
1275           th->context.EFlags |= FLAG_TRACE_BIT;
1276         }
1277
1278       if (th->context.ContextFlags)
1279         {
1280           CHECK (SetThreadContext (th->h, &th->context));
1281           th->context.ContextFlags = 0;
1282         }
1283     }
1284
1285   /* Allow continuing with the same signal that interrupted us.
1286      Otherwise complain. */
1287
1288   child_continue (continue_status, pid);
1289 }
1290
1291 static void
1292 child_prepare_to_store ()
1293 {
1294   /* Do nothing, since we can store individual regs */
1295 }
1296
1297 static int
1298 child_can_run ()
1299 {
1300   return 1;
1301 }
1302
1303 static void
1304 child_close ()
1305 {
1306   DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1307 }
1308
1309 struct target_ops child_ops;
1310
1311 static void
1312 init_child_ops (void)
1313 {
1314   child_ops.to_shortname = "child";
1315   child_ops.to_longname = "Win32 child process";
1316   child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1317   child_ops.to_open = child_open;
1318   child_ops.to_close = child_close;
1319   child_ops.to_attach = child_attach;
1320   child_ops.to_detach = child_detach;
1321   child_ops.to_resume = child_resume;
1322   child_ops.to_wait = child_wait;
1323   child_ops.to_fetch_registers = child_fetch_inferior_registers;
1324   child_ops.to_store_registers = child_store_inferior_registers;
1325   child_ops.to_prepare_to_store = child_prepare_to_store;
1326   child_ops.to_xfer_memory = child_xfer_memory;
1327   child_ops.to_files_info = child_files_info;
1328   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1329   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1330   child_ops.to_terminal_init = terminal_init_inferior;
1331   child_ops.to_terminal_inferior = terminal_inferior;
1332   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1333   child_ops.to_terminal_ours = terminal_ours;
1334   child_ops.to_terminal_info = child_terminal_info;
1335   child_ops.to_kill = child_kill_inferior;
1336   child_ops.to_load = 0;
1337   child_ops.to_lookup_symbol = 0;
1338   child_ops.to_create_inferior = child_create_inferior;
1339   child_ops.to_mourn_inferior = child_mourn_inferior;
1340   child_ops.to_can_run = child_can_run;
1341   child_ops.to_notice_signals = 0;
1342   child_ops.to_thread_alive = win32_child_thread_alive;
1343   child_ops.to_pid_to_str = cygwin_pid_to_str;
1344   child_ops.to_stop = child_stop;
1345   child_ops.to_stratum = process_stratum;
1346   child_ops.DONT_USE = 0;
1347   child_ops.to_has_all_memory = 1;
1348   child_ops.to_has_memory = 1;
1349   child_ops.to_has_stack = 1;
1350   child_ops.to_has_registers = 1;
1351   child_ops.to_has_execution = 1;
1352   child_ops.to_sections = 0;
1353   child_ops.to_sections_end = 0;
1354   child_ops.to_magic = OPS_MAGIC;
1355 }
1356
1357 void
1358 _initialize_inftarg ()
1359 {
1360   init_child_ops ();
1361
1362   add_com ("dll-symbols", class_files, dll_symbol_command,
1363            "Load dll library symbols from FILE.");
1364
1365   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1366
1367   add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1368                   (char *) &new_console,
1369                   "Set creation of new console when creating child process.",
1370                   &setlist),
1371      &showlist);
1372
1373   add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1374                   (char *) &new_group,
1375                   "Set creation of new group when creating child process.",
1376                   &setlist),
1377      &showlist);
1378
1379   add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1380                   (char *) &debug_exec,
1381                   "Set whether to display execution in child process.",
1382                   &setlist),
1383      &showlist);
1384
1385   add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1386                   (char *) &debug_events,
1387                   "Set whether to display kernel events in child process.",
1388                   &setlist),
1389      &showlist);
1390
1391   add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1392                   (char *) &debug_memory,
1393                   "Set whether to display memory accesses in child process.",
1394                   &setlist),
1395      &showlist);
1396
1397   add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1398                   (char *) &debug_exceptions,
1399                   "Set whether to display kernel exceptions in child process.",
1400                   &setlist),
1401      &showlist);
1402
1403   add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1404   add_info_alias ("sharedlibrary", "dll", 1);
1405
1406   add_target (&child_ops);
1407 }
1408
1409 /* Determine if the thread referenced by "pid" is alive
1410    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1411    it means that the pid has died.  Otherwise it is assumed to be alive. */
1412 static int
1413 win32_child_thread_alive (int pid)
1414 {
1415   return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1416     FALSE : TRUE;
1417 }
1418
1419 /* Convert pid to printable format. */
1420 char *
1421 cygwin_pid_to_str (int pid)
1422 {
1423   static char buf[80];
1424   if ((DWORD) pid == current_event.dwProcessId)
1425     sprintf (buf, "process %d", pid);
1426   else
1427     sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1428   return buf;
1429 }