Eliminate PARAMS.
[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 objfile *ret;
426 };
427
428 /* Call symbol_file_add with stderr redirected.  We don't care if there
429    are errors. */
430 static int
431 safe_symbol_file_add_stub (void *argv)
432 {
433 #define p ((struct safe_symbol_file_add_args *)argv)
434   p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
435   return !!p->ret;
436 #undef p
437 }
438
439 /* Restore gdb's stderr after calling symbol_file_add */
440 static void
441 safe_symbol_file_add_cleanup (void *gdb_stderrv)
442 {
443   gdb_flush (gdb_stderr);
444   ui_file_delete (gdb_stderr);
445   gdb_stderr = (struct ui_file *)gdb_stderrv;
446 }
447
448 /* symbol_file_add wrapper that prevents errors from being displayed. */
449 static struct objfile *
450 safe_symbol_file_add (char *name, int from_tty,
451                       struct section_addr_info *addrs,
452                       int mainline, int flags)
453
454 {
455   struct safe_symbol_file_add_args p;
456   struct cleanup *cleanup;
457
458   cleanup = make_cleanup (safe_symbol_file_add_cleanup, gdb_stderr);
459
460   gdb_flush (gdb_stderr);
461   gdb_stderr = ui_file_new ();
462   p.name = name;
463   p.from_tty = from_tty;
464   p.addrs = addrs;
465   p.mainline = mainline;
466   p.flags = flags;
467   catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
468
469   do_cleanups (cleanup);
470   return p.ret;
471 }
472
473 /* Maintain a linked list of "so" information. */
474 struct so_stuff
475 {
476   struct so_stuff *next, **last;
477   DWORD load_addr;
478   char name[0];
479 } solib_start, *solib_end;
480
481 /* Remember the maximum DLL length for printing in info dll command. */
482 int max_dll_name_len;
483
484 /* Wait for child to do something.  Return pid of child, or -1 in case
485    of error; store status through argument pointer OURSTATUS.  */
486 static int
487 handle_load_dll (PTR dummy ATTRIBUTE_UNUSED)
488 {
489   LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
490   DWORD dll_name_ptr;
491   DWORD done;
492   char dll_buf[MAX_PATH + 1];
493   struct so_stuff *so, *solast;
494   char *dll_name = NULL;
495   DWORD dll_base = 0;
496   int len;
497   char *p;
498
499   dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
500
501   if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
502     dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
503
504   dll_name = dll_buf;
505
506   /* Attempt to read the name of the dll that was detected.
507      This is documented to work only when actively debugging
508      a program.  It will not work for attached processes. */
509   if (dll_name == NULL || *dll_name == '\0')
510     {
511       DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
512       int len = 0;
513       char b[2];
514
515       ReadProcessMemory (current_process_handle,
516                          (LPCVOID) event->lpImageName,
517                          (char *) &dll_name_ptr,
518                          sizeof (dll_name_ptr), &done);
519
520       /* See if we could read the address of a string, and that the
521          address isn't null. */
522
523       if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
524         return 1;
525
526       do
527         {
528           ReadProcessMemory (current_process_handle,
529                              (LPCVOID) (dll_name_ptr + len * size),
530                              &b,
531                              size,
532                              &done);
533           len++;
534         }
535       while ((b[0] != 0 || b[size - 1] != 0) && done == size);
536
537       dll_name = alloca (len);
538
539       if (event->fUnicode)
540         {
541           WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
542           ReadProcessMemory (current_process_handle,
543                              (LPCVOID) dll_name_ptr,
544                              unicode_dll_name,
545                              len * sizeof (WCHAR),
546                              &done);
547
548           WideCharToMultiByte (CP_ACP, 0,
549                                unicode_dll_name, len,
550                                dll_name, len, 0, 0);
551         }
552       else
553         {
554           ReadProcessMemory (current_process_handle,
555                              (LPCVOID) dll_name_ptr,
556                              dll_name,
557                              len,
558                              &done);
559         }
560     }
561
562   if (!dll_name)
563     return 1;
564
565   (void) strlwr (dll_name);
566
567   while ((p = strchr (dll_name, '\\')))
568     *p = '/';
569
570   so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) +  strlen (dll_name) + 8 + 2);
571   so->load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
572   strcpy (so->name, dll_name);
573
574   solib_end->next = so;
575   solib_end = so;
576   so->next = NULL;
577
578   len = strlen (dll_name);
579   if (len > max_dll_name_len)
580     max_dll_name_len = len;
581
582   return 1;
583 }
584
585 /* Return name of last loaded DLL. */
586 char *
587 child_solib_loaded_library_pathname (int pid)
588 {
589   return !solib_end || !solib_end->name[0]? NULL : solib_end->name;
590 }
591
592 /* Clear list of loaded DLLs. */
593 void
594 child_clear_solibs (void)
595 {
596   struct so_stuff *so, *so1 = solib_start.next;
597
598   while ((so = so1) != NULL)
599     {
600       so1 = so->next;
601       free (so);
602     }
603
604   solib_start.next = NULL;
605   solib_end = &solib_start;
606   max_dll_name_len = sizeof ("DLL Name") - 1;
607 }
608
609 /* Add DLL symbol information. */
610 void
611 child_solib_add (char *filename, int from_tty, struct target_ops *t)
612 {
613   struct section_addr_info section_addrs;
614
615   /* The symbols in a dll are offset by 0x1000, which is the
616      the offset from 0 of the first byte in an image - because
617      of the file header and the section alignment. */
618
619   if (!solib_end || !solib_end->name[0])
620     return;
621
622   memset (&section_addrs, 0, sizeof (section_addrs));
623   section_addrs.other[0].name = ".text";
624   section_addrs.other[0].addr = solib_end->load_addr;
625   safe_symbol_file_add (solib_end->name, 0, &section_addrs, 0, OBJF_SHARED);
626
627   return;
628 }
629
630 /* Load DLL symbol info. */
631 void
632 dll_symbol_command (char *args, int from_tty)
633 {
634   struct section_addr_info section_addrs;
635
636   dont_repeat ();
637   
638   if (args == NULL)
639     error ("dll-symbols requires a file name");
640
641   safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED);
642
643
644 /* List currently loaded DLLs. */
645 void
646 info_dll_command (char *ignore, int from_tty)
647 {
648   struct so_stuff *so = &solib_start;
649
650   if (!so->next)
651     return;
652
653   printf ("%*s  Load Address\n", -max_dll_name_len, "DLL Name");
654   while ((so = so->next) != NULL)
655     printf_unfiltered ("%*s  %08lx\n", -max_dll_name_len, so->name, so->load_addr);
656
657   return;
658 }
659
660 /* Handle DEBUG_STRING output from child process.
661    Cygwin prepends its messages with a "cygwin:".  Interpret this as
662    a Cygwin signal.  Otherwise just print the string as a warning. */
663 static int
664 handle_output_debug_string (struct target_waitstatus *ourstatus)
665 {
666   char *s;
667   int gotasig = FALSE;
668
669   if (!target_read_string
670     ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
671       || !s || !*s)
672     return gotasig;
673
674   if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
675     {
676       if (strncmp (s, "cYg", 3) != 0)
677         warning ("%s", s);
678     }
679   else
680     {
681       char *p;
682       int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
683       gotasig = target_signal_from_host (sig);
684       ourstatus->value.sig = gotasig;
685       if (gotasig)
686         ourstatus->kind = TARGET_WAITKIND_STOPPED;
687     }
688
689   free (s);
690   return gotasig;
691 }
692
693 static int
694 handle_exception (struct target_waitstatus *ourstatus)
695 {
696   thread_info *th;
697   DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
698
699   ourstatus->kind = TARGET_WAITKIND_STOPPED;
700
701   /* Record the context of the current thread */
702   th = thread_rec (current_event.dwThreadId, -1);
703
704   last_sig = 0;
705
706   switch (code)
707     {
708     case EXCEPTION_ACCESS_VIOLATION:
709       DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
710                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
711       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
712       last_sig = SIGSEGV;
713       break;
714     case STATUS_FLOAT_UNDERFLOW:
715     case STATUS_FLOAT_DIVIDE_BY_ZERO:
716     case STATUS_FLOAT_OVERFLOW:
717     case STATUS_INTEGER_DIVIDE_BY_ZERO:
718       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
719                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
720       ourstatus->value.sig = TARGET_SIGNAL_FPE;
721       last_sig = SIGFPE;
722       break;
723     case STATUS_STACK_OVERFLOW:
724       DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
725                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
726       ourstatus->value.sig = TARGET_SIGNAL_SEGV;
727       break;
728     case EXCEPTION_BREAKPOINT:
729       DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
730                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
731       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
732       break;
733     case DBG_CONTROL_C:
734       DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
735                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
736       ourstatus->value.sig = TARGET_SIGNAL_INT;
737       last_sig = SIGINT;        /* FIXME - should check pass state */
738       break;
739     case EXCEPTION_SINGLE_STEP:
740       DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
741                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
742       ourstatus->value.sig = TARGET_SIGNAL_TRAP;
743       break;
744     case EXCEPTION_ILLEGAL_INSTRUCTION:
745       DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
746                (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
747       ourstatus->value.sig = TARGET_SIGNAL_ILL;
748       last_sig = SIGILL;
749       break;
750     default:
751       printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
752                     current_event.u.Exception.ExceptionRecord.ExceptionCode,
753                 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
754       ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
755       break;
756     }
757   exception_count++;
758   return 1;
759 }
760
761 /* Resume all artificially suspended threads if we are continuing
762    execution */
763 static BOOL
764 child_continue (DWORD continue_status, int id)
765 {
766   int i;
767   thread_info *th;
768   BOOL res;
769
770   DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
771                  current_event.dwProcessId, current_event.dwThreadId));
772   res = ContinueDebugEvent (current_event.dwProcessId,
773                             current_event.dwThreadId,
774                             continue_status);
775   continue_status = 0;
776   if (res)
777     for (th = &thread_head; (th = th->next) != NULL;)
778       if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
779         {
780           for (i = 0; i < th->suspend_count; i++)
781             (void) ResumeThread (th->h);
782           th->suspend_count = 0;
783         }
784
785   return res;
786 }
787
788 /* Get the next event from the child.  Return 1 if the event requires
789    handling by WFI (or whatever).
790  */
791 static int
792 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
793 {
794   int breakout = 0;
795   BOOL debug_event;
796   DWORD continue_status, event_code;
797   thread_info *th = NULL;
798   static thread_info dummy_thread_info;
799   int retval = 0;
800
801   if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
802     goto out;
803
804   event_count++;
805   continue_status = DBG_CONTINUE;
806
807   event_code = current_event.dwDebugEventCode;
808   ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
809
810   switch (event_code)
811     {
812     case CREATE_THREAD_DEBUG_EVENT:
813       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
814                      (unsigned) current_event.dwProcessId,
815                      (unsigned) current_event.dwThreadId,
816                      "CREATE_THREAD_DEBUG_EVENT"));
817       /* Record the existence of this thread */
818       th = child_add_thread (current_event.dwThreadId,
819                              current_event.u.CreateThread.hThread);
820       if (info_verbose)
821         printf_unfiltered ("[New %s]\n",
822                            target_pid_to_str (current_event.dwThreadId));
823       retval = current_event.dwThreadId;
824       break;
825
826     case EXIT_THREAD_DEBUG_EVENT:
827       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
828                      (unsigned) current_event.dwProcessId,
829                      (unsigned) current_event.dwThreadId,
830                      "EXIT_THREAD_DEBUG_EVENT"));
831       child_delete_thread (current_event.dwThreadId);
832       th = &dummy_thread_info;
833       break;
834
835     case CREATE_PROCESS_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                      "CREATE_PROCESS_DEBUG_EVENT"));
840       current_process_handle = current_event.u.CreateProcessInfo.hProcess;
841
842       main_thread_id = inferior_pid = current_event.dwThreadId;
843       /* Add the main thread */
844       th = child_add_thread (current_event.dwProcessId,
845                              current_event.u.CreateProcessInfo.hProcess);
846       th = child_add_thread (inferior_pid,
847                              current_event.u.CreateProcessInfo.hThread);
848       retval = ourstatus->value.related_pid = current_event.dwProcessId;
849       break;
850
851     case EXIT_PROCESS_DEBUG_EVENT:
852       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
853                      (unsigned) current_event.dwProcessId,
854                      (unsigned) current_event.dwThreadId,
855                      "EXIT_PROCESS_DEBUG_EVENT"));
856       ourstatus->kind = TARGET_WAITKIND_EXITED;
857       ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
858       CloseHandle (current_process_handle);
859       retval = current_event.dwProcessId;
860       break;
861
862     case LOAD_DLL_DEBUG_EVENT:
863       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
864                      (unsigned) current_event.dwProcessId,
865                      (unsigned) current_event.dwThreadId,
866                      "LOAD_DLL_DEBUG_EVENT"));
867       catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
868       registers_changed ();     /* mark all regs invalid */
869       ourstatus->kind = TARGET_WAITKIND_LOADED;
870       ourstatus->value.integer = 0;
871       retval = current_event.dwProcessId;
872       break;
873
874     case UNLOAD_DLL_DEBUG_EVENT:
875       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
876                      (unsigned) current_event.dwProcessId,
877                      (unsigned) current_event.dwThreadId,
878                      "UNLOAD_DLL_DEBUG_EVENT"));
879       break;                    /* FIXME: don't know what to do here */
880
881     case EXCEPTION_DEBUG_EVENT:
882       DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
883                      (unsigned) current_event.dwProcessId,
884                      (unsigned) current_event.dwThreadId,
885                      "EXCEPTION_DEBUG_EVENT"));
886       handle_exception (ourstatus);
887       retval = current_event.dwThreadId;
888       break;
889
890     case OUTPUT_DEBUG_STRING_EVENT:     /* message from the kernel */
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                      "OUTPUT_DEBUG_STRING_EVENT"));
895       if (handle_output_debug_string ( ourstatus))
896         retval = current_event.dwProcessId;
897       break;
898     default:
899       printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
900                          (DWORD) current_event.dwProcessId,
901                          (DWORD) current_event.dwThreadId);
902       printf_unfiltered ("                 unknown event code %ld\n",
903                          current_event.dwDebugEventCode);
904       break;
905     }
906
907   if (!retval)
908     CHECK (child_continue (continue_status, -1));
909   else
910     current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
911
912 out:
913   return retval;
914 }
915
916 /* Wait for interesting events to occur in the target process. */
917 static int
918 child_wait (int pid, struct target_waitstatus *ourstatus)
919 {
920   /* We loop when we get a non-standard exception rather than return
921      with a SPURIOUS because resume can try and step or modify things,
922      which needs a current_thread->h.  But some of these exceptions mark
923      the birth or death of threads, which mean that the current thread
924      isn't necessarily what you think it is. */
925
926   while (1)
927     {
928       int retval = get_child_debug_event (pid, ourstatus);
929       if (retval)
930         return retval;
931       else
932         {
933           int detach = 0;
934
935           if (ui_loop_hook != NULL)
936             detach = ui_loop_hook (0);
937
938           if (detach)
939             child_kill_inferior ();
940         }
941     }
942 }
943
944 /* Attach to process PID, then initialize for debugging it.  */
945
946 static void
947 child_attach (args, from_tty)
948      char *args;
949      int from_tty;
950 {
951   BOOL ok;
952
953   if (!args)
954     error_no_arg ("process-id to attach");
955
956   current_event.dwProcessId = strtoul (args, 0, 0);
957
958   ok = DebugActiveProcess (current_event.dwProcessId);
959
960   if (!ok)
961     error ("Can't attach to process.");
962
963   exception_count = 0;
964   event_count = 0;
965
966   child_init_thread_list ();
967   child_clear_solibs ();
968
969   if (from_tty)
970     {
971       char *exec_file = (char *) get_exec_file (0);
972
973       if (exec_file)
974         printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
975                            target_pid_to_str (current_event.dwProcessId));
976       else
977         printf_unfiltered ("Attaching to %s\n",
978                            target_pid_to_str (current_event.dwProcessId));
979
980       gdb_flush (gdb_stdout);
981     }
982
983   push_target (&child_ops);
984 }
985
986 static void
987 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
988 {
989   if (from_tty)
990     {
991       char *exec_file = get_exec_file (0);
992       if (exec_file == 0)
993         exec_file = "";
994       printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
995                          target_pid_to_str (inferior_pid));
996       gdb_flush (gdb_stdout);
997     }
998   inferior_pid = 0;
999   unpush_target (&child_ops);
1000 }
1001
1002 /* Print status information about what we're accessing.  */
1003
1004 static void
1005 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1006 {
1007   printf_unfiltered ("\tUsing the running image of %s %s.\n",
1008       attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
1009 }
1010
1011 /* ARGSUSED */
1012 static void
1013 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1014 {
1015   error ("Use the \"run\" command to start a Unix child process.");
1016 }
1017
1018 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1019    EXEC_FILE is the file to run.
1020    ALLARGS is a string containing the arguments to the program.
1021    ENV is the environment vector to pass.  Errors reported with error().  */
1022
1023 static void
1024 child_create_inferior (exec_file, allargs, env)
1025      char *exec_file;
1026      char *allargs;
1027      char **env;
1028 {
1029   char real_path[MAXPATHLEN];
1030   char *winenv;
1031   char *temp;
1032   int envlen;
1033   int i;
1034   STARTUPINFO si;
1035   PROCESS_INFORMATION pi;
1036   struct target_waitstatus dummy;
1037   BOOL ret;
1038   DWORD flags;
1039   char *args;
1040   extern int stop_after_trap;
1041
1042   if (!exec_file)
1043     error ("No executable specified, use `target exec'.\n");
1044
1045   memset (&si, 0, sizeof (si));
1046   si.cb = sizeof (si);
1047
1048   cygwin_conv_to_win32_path (exec_file, real_path);
1049
1050   flags = DEBUG_ONLY_THIS_PROCESS;
1051
1052   if (new_group)
1053     flags |= CREATE_NEW_PROCESS_GROUP;
1054
1055   if (new_console)
1056     flags |= CREATE_NEW_CONSOLE;
1057
1058   args = alloca (strlen (real_path) + strlen (allargs) + 2);
1059
1060   strcpy (args, real_path);
1061
1062   strcat (args, " ");
1063   strcat (args, allargs);
1064
1065   /* Prepare the environment vars for CreateProcess.  */
1066   {
1067     /* This code use to assume all env vars were file names and would
1068        translate them all to win32 style.  That obviously doesn't work in the
1069        general case.  The current rule is that we only translate PATH.
1070        We need to handle PATH because we're about to call CreateProcess and
1071        it uses PATH to find DLL's.  Fortunately PATH has a well-defined value
1072        in both posix and win32 environments.  cygwin.dll will change it back
1073        to posix style if necessary.  */
1074
1075     static const char *conv_path_names[] =
1076     {
1077       "PATH=",
1078       0
1079     };
1080
1081     /* CreateProcess takes the environment list as a null terminated set of
1082        strings (i.e. two nulls terminate the list).  */
1083
1084     /* Get total size for env strings.  */
1085     for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1086       {
1087         int j, len;
1088
1089         for (j = 0; conv_path_names[j]; j++)
1090           {
1091             len = strlen (conv_path_names[j]);
1092             if (strncmp (conv_path_names[j], env[i], len) == 0)
1093               {
1094                 if (cygwin_posix_path_list_p (env[i] + len))
1095                   envlen += len
1096                     + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1097                 else
1098                   envlen += strlen (env[i]) + 1;
1099                 break;
1100               }
1101           }
1102         if (conv_path_names[j] == NULL)
1103           envlen += strlen (env[i]) + 1;
1104       }
1105
1106     winenv = alloca (envlen + 1);
1107
1108     /* Copy env strings into new buffer.  */
1109     for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1110       {
1111         int j, len;
1112
1113         for (j = 0; conv_path_names[j]; j++)
1114           {
1115             len = strlen (conv_path_names[j]);
1116             if (strncmp (conv_path_names[j], env[i], len) == 0)
1117               {
1118                 if (cygwin_posix_path_list_p (env[i] + len))
1119                   {
1120                     memcpy (temp, env[i], len);
1121                     cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1122                   }
1123                 else
1124                   strcpy (temp, env[i]);
1125                 break;
1126               }
1127           }
1128         if (conv_path_names[j] == NULL)
1129           strcpy (temp, env[i]);
1130
1131         temp += strlen (temp) + 1;
1132       }
1133
1134     /* Final nil string to terminate new env.  */
1135     *temp = 0;
1136   }
1137
1138   ret = CreateProcess (0,
1139                        args,    /* command line */
1140                        NULL,    /* Security */
1141                        NULL,    /* thread */
1142                        TRUE,    /* inherit handles */
1143                        flags,   /* start flags */
1144                        winenv,
1145                        NULL,    /* current directory */
1146                        &si,
1147                        &pi);
1148   if (!ret)
1149     error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1150
1151   exception_count = 0;
1152   event_count = 0;
1153
1154   current_process_handle = pi.hProcess;
1155   current_event.dwProcessId = pi.dwProcessId;
1156   memset (&current_event, 0, sizeof (current_event));
1157   inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1158   push_target (&child_ops);
1159   child_init_thread_list ();
1160   child_clear_solibs ();
1161   clear_proceed_status ();
1162   init_wait_for_inferior ();
1163   target_terminal_init ();
1164   target_terminal_inferior ();
1165   last_sig = 0;
1166
1167   while (1)
1168     {
1169       stop_after_trap = 1;
1170       wait_for_inferior ();
1171       if (stop_signal != TARGET_SIGNAL_TRAP)
1172         resume (0, stop_signal);
1173       else
1174         break;
1175     }
1176   stop_after_trap = 0;
1177
1178   /* child_continue (DBG_CONTINUE, -1);*/
1179   proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1180 }
1181
1182 static void
1183 child_mourn_inferior ()
1184 {
1185   (void) child_continue (DBG_CONTINUE, -1);
1186   unpush_target (&child_ops);
1187   generic_mourn_inferior ();
1188 }
1189
1190 /* Send a SIGINT to the process group.  This acts just like the user typed a
1191    ^C on the controlling terminal. */
1192
1193 static void
1194 child_stop ()
1195 {
1196   DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1197   CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1198   registers_changed ();         /* refresh register state */
1199 }
1200
1201 int
1202 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1203                    int write, struct target_ops *target ATTRIBUTE_UNUSED)
1204 {
1205   DWORD done;
1206   if (write)
1207     {
1208       DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1209                   len, (DWORD) memaddr));
1210       WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1211                           len, &done);
1212       FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1213     }
1214   else
1215     {
1216       DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1217                   len, (DWORD) memaddr));
1218       ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1219                          &done);
1220     }
1221   return done;
1222 }
1223
1224 void
1225 child_kill_inferior (void)
1226 {
1227   CHECK (TerminateProcess (current_process_handle, 0));
1228
1229   for (;;)
1230     {
1231       if (!child_continue (DBG_CONTINUE, -1))
1232         break;
1233       if (!WaitForDebugEvent (&current_event, INFINITE))
1234         break;
1235       if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1236         break;
1237     }
1238
1239   CHECK (CloseHandle (current_process_handle));
1240
1241   /* this may fail in an attached process so don't check. */
1242   (void) CloseHandle (current_thread->h);
1243   target_mourn_inferior ();     /* or just child_mourn_inferior? */
1244 }
1245
1246 void
1247 child_resume (int pid, int step, enum target_signal sig)
1248 {
1249   thread_info *th;
1250   DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1251                           DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1252
1253   last_sig = 0;
1254
1255   DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1256                pid, step, sig));
1257
1258   /* Get context for currently selected thread */
1259   th = thread_rec (current_event.dwThreadId, FALSE);
1260   if (th)
1261     {
1262       if (step)
1263         {
1264           /* Single step by setting t bit */
1265           child_fetch_inferior_registers (PS_REGNUM);
1266           th->context.EFlags |= FLAG_TRACE_BIT;
1267         }
1268
1269       if (th->context.ContextFlags)
1270         {
1271           CHECK (SetThreadContext (th->h, &th->context));
1272           th->context.ContextFlags = 0;
1273         }
1274     }
1275
1276   /* Allow continuing with the same signal that interrupted us.
1277      Otherwise complain. */
1278
1279   child_continue (continue_status, pid);
1280 }
1281
1282 static void
1283 child_prepare_to_store ()
1284 {
1285   /* Do nothing, since we can store individual regs */
1286 }
1287
1288 static int
1289 child_can_run ()
1290 {
1291   return 1;
1292 }
1293
1294 static void
1295 child_close ()
1296 {
1297   DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1298 }
1299
1300 struct target_ops child_ops;
1301
1302 static void
1303 init_child_ops (void)
1304 {
1305   child_ops.to_shortname = "child";
1306   child_ops.to_longname = "Win32 child process";
1307   child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1308   child_ops.to_open = child_open;
1309   child_ops.to_close = child_close;
1310   child_ops.to_attach = child_attach;
1311   child_ops.to_detach = child_detach;
1312   child_ops.to_resume = child_resume;
1313   child_ops.to_wait = child_wait;
1314   child_ops.to_fetch_registers = child_fetch_inferior_registers;
1315   child_ops.to_store_registers = child_store_inferior_registers;
1316   child_ops.to_prepare_to_store = child_prepare_to_store;
1317   child_ops.to_xfer_memory = child_xfer_memory;
1318   child_ops.to_files_info = child_files_info;
1319   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1320   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1321   child_ops.to_terminal_init = terminal_init_inferior;
1322   child_ops.to_terminal_inferior = terminal_inferior;
1323   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1324   child_ops.to_terminal_ours = terminal_ours;
1325   child_ops.to_terminal_info = child_terminal_info;
1326   child_ops.to_kill = child_kill_inferior;
1327   child_ops.to_load = 0;
1328   child_ops.to_lookup_symbol = 0;
1329   child_ops.to_create_inferior = child_create_inferior;
1330   child_ops.to_mourn_inferior = child_mourn_inferior;
1331   child_ops.to_can_run = child_can_run;
1332   child_ops.to_notice_signals = 0;
1333   child_ops.to_thread_alive = win32_child_thread_alive;
1334   child_ops.to_pid_to_str = cygwin_pid_to_str;
1335   child_ops.to_stop = child_stop;
1336   child_ops.to_stratum = process_stratum;
1337   child_ops.DONT_USE = 0;
1338   child_ops.to_has_all_memory = 1;
1339   child_ops.to_has_memory = 1;
1340   child_ops.to_has_stack = 1;
1341   child_ops.to_has_registers = 1;
1342   child_ops.to_has_execution = 1;
1343   child_ops.to_sections = 0;
1344   child_ops.to_sections_end = 0;
1345   child_ops.to_magic = OPS_MAGIC;
1346 }
1347
1348 void
1349 _initialize_inftarg ()
1350 {
1351   init_child_ops ();
1352
1353   add_com ("dll-symbols", class_files, dll_symbol_command,
1354            "Load dll library symbols from FILE.");
1355
1356   add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1357
1358   add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1359                   (char *) &new_console,
1360                   "Set creation of new console when creating child process.",
1361                   &setlist),
1362      &showlist);
1363
1364   add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1365                   (char *) &new_group,
1366                   "Set creation of new group when creating child process.",
1367                   &setlist),
1368      &showlist);
1369
1370   add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1371                   (char *) &debug_exec,
1372                   "Set whether to display execution in child process.",
1373                   &setlist),
1374      &showlist);
1375
1376   add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1377                   (char *) &debug_events,
1378                   "Set whether to display kernel events in child process.",
1379                   &setlist),
1380      &showlist);
1381
1382   add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1383                   (char *) &debug_memory,
1384                   "Set whether to display memory accesses in child process.",
1385                   &setlist),
1386      &showlist);
1387
1388   add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1389                   (char *) &debug_exceptions,
1390                   "Set whether to display kernel exceptions in child process.",
1391                   &setlist),
1392      &showlist);
1393
1394   add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1395   add_info_alias ("sharedlibrary", "dll", 1);
1396
1397   add_target (&child_ops);
1398 }
1399
1400 /* Determine if the thread referenced by "pid" is alive
1401    by "polling" it.  If WaitForSingleObject returns WAIT_OBJECT_0
1402    it means that the pid has died.  Otherwise it is assumed to be alive. */
1403 static int
1404 win32_child_thread_alive (int pid)
1405 {
1406   return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1407     FALSE : TRUE;
1408 }
1409
1410 /* Convert pid to printable format. */
1411 char *
1412 cygwin_pid_to_str (int pid)
1413 {
1414   static char buf[80];
1415   if ((DWORD) pid == current_event.dwProcessId)
1416     sprintf (buf, "process %d", pid);
1417   else
1418     sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
1419   return buf;
1420 }