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