import gdb-1999-08-30 snapshot
[deliverable/binutils-gdb.git] / gdb / win32-nat.c
CommitLineData
c906108c
SS
1/* Target-vector operations for controlling win32 child processes, for GDB.
2 Copyright 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
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"
31#include "wait.h"
32#include "gdbcore.h"
33#include "command.h"
34#include <signal.h>
35#include <sys/types.h>
36#include <fcntl.h>
37#include <stdlib.h>
38
39#ifdef _MSC_VER
40#include "windefs.h"
41#else /* other WIN32 compiler */
42#include <windows.h>
43#endif
44
45#include "buildsym.h"
46#include "symfile.h"
47#include "objfiles.h"
48#include "gdb_string.h"
49#include "gdbthread.h"
50#include "gdbcmd.h"
51#include <sys/param.h>
c906108c 52
7a292a7a
SS
53/* The ui's event loop. */
54extern int (*ui_loop_hook) PARAMS ((int signo));
55
56/* If we're not using the old Cygwin header file set, define the
57 following which never should have been in the generic Win32 API
58 headers in the first place since they were our own invention... */
59#ifndef _GNU_H_WINDOWS_H
60#define FLAG_TRACE_BIT 0x100
61#define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
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
68#define CHECK(x) check (x, __FILE__,__LINE__)
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
77static void child_stop PARAMS ((void));
78static int win32_child_thread_alive PARAMS ((int));
7a292a7a 79void child_kill_inferior PARAMS ((void));
c906108c
SS
80
81static int last_sig = 0; /* Set if a signal was received from the
82 debugged process */
83
84/* Thread information structure used to track information that is
85 not available in gdb's thread structure. */
86typedef struct thread_info_struct
c5aa993b
JM
87 {
88 struct thread_info_struct *next;
89 DWORD id;
90 HANDLE h;
91 char *name;
92 int suspend_count;
93 CONTEXT context;
94 }
95thread_info;
c906108c 96
c5aa993b
JM
97static thread_info thread_head =
98{NULL};
c906108c
SS
99
100/* The process and thread handles for the above context. */
101
102static DEBUG_EVENT current_event; /* The current debug event from
103 WaitForDebugEvent */
104static HANDLE current_process_handle; /* Currently executing process */
105static thread_info *current_thread; /* Info on currently selected thread */
c5aa993b 106static DWORD main_thread_id; /* Thread ID of the main thread */
c906108c
SS
107
108/* Counts of things. */
109static int exception_count = 0;
110static int event_count = 0;
111
112/* User options. */
113static int new_console = 0;
114static int new_group = 0;
c5aa993b
JM
115static int debug_exec = 0; /* show execution */
116static int debug_events = 0; /* show events from kernel */
117static int debug_memory = 0; /* show target memory accesses */
c906108c
SS
118static int debug_exceptions = 0; /* show target exceptions */
119
120/* This vector maps GDB's idea of a register's number into an address
121 in the win32 exception context vector.
122
123 It also contains the bit mask needed to load the register in question.
124
125 One day we could read a reg, we could inspect the context we
126 already have loaded, if it doesn't have the bit set that we need,
127 we read that set of registers in using GetThreadContext. If the
128 context already contains what we need, we just unpack it. Then to
129 write a register, first we have to ensure that the context contains
130 the other regs of the group, and then we copy the info in and set
131 out bit. */
132
133#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
134static const int mappings[] =
135{
c5aa993b
JM
136 context_offset (Eax),
137 context_offset (Ecx),
138 context_offset (Edx),
139 context_offset (Ebx),
140 context_offset (Esp),
141 context_offset (Ebp),
142 context_offset (Esi),
143 context_offset (Edi),
144 context_offset (Eip),
145 context_offset (EFlags),
146 context_offset (SegCs),
147 context_offset (SegSs),
148 context_offset (SegDs),
149 context_offset (SegEs),
150 context_offset (SegFs),
151 context_offset (SegGs),
152 context_offset (FloatSave.RegisterArea[0 * 10]),
153 context_offset (FloatSave.RegisterArea[1 * 10]),
154 context_offset (FloatSave.RegisterArea[2 * 10]),
155 context_offset (FloatSave.RegisterArea[3 * 10]),
156 context_offset (FloatSave.RegisterArea[4 * 10]),
157 context_offset (FloatSave.RegisterArea[5 * 10]),
158 context_offset (FloatSave.RegisterArea[6 * 10]),
159 context_offset (FloatSave.RegisterArea[7 * 10]),
c906108c
SS
160};
161
162/* This vector maps the target's idea of an exception (extracted
163 from the DEBUG_EVENT structure) to GDB's idea. */
164
165struct xlate_exception
166 {
167 int them;
168 enum target_signal us;
169 };
170
171static const struct xlate_exception
172 xlate[] =
173{
174 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
175 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
176 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
177 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
178 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
179 {-1, -1}};
180
181/* Find a thread record given a thread id.
182 If get_context then also retrieve the context for this
183 thread. */
184static thread_info *
185thread_rec (DWORD id, int get_context)
186{
187 thread_info *th;
188
c5aa993b 189 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
190 if (th->id == id)
191 {
192 if (!th->suspend_count && get_context)
193 {
194 if (get_context > 0)
195 th->suspend_count = SuspendThread (th->h) + 1;
196 else if (get_context < 0)
197 th->suspend_count = -1;
198
199 th->context.ContextFlags = CONTEXT_DEBUGGER;
200 GetThreadContext (th->h, &th->context);
201 }
202 return th;
203 }
204
205 return NULL;
206}
207
208/* Add a thread to the thread list */
209static thread_info *
c5aa993b 210child_add_thread (DWORD id, HANDLE h)
c906108c
SS
211{
212 thread_info *th;
213
214 if ((th = thread_rec (id, FALSE)))
215 return th;
216
217 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 218 memset (th, 0, sizeof (*th));
c906108c
SS
219 th->id = id;
220 th->h = h;
221 th->next = thread_head.next;
222 thread_head.next = th;
223 add_thread (id);
224 return th;
225}
226
227/* Clear out any old thread list and reintialize it to a
228 pristine state. */
229static void
230child_init_thread_list ()
231{
232 thread_info *th = &thread_head;
233
234 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
235 init_thread_list ();
236 while (th->next != NULL)
237 {
238 thread_info *here = th->next;
239 th->next = here->next;
240 (void) CloseHandle (here->h);
241 free (here);
242 }
243}
244
245/* Delete a thread from the list of threads */
246static void
247child_delete_thread (DWORD id)
248{
249 thread_info *th;
250
251 if (info_verbose)
252 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
253 delete_thread (id);
254
255 for (th = &thread_head;
256 th->next != NULL && th->next->id != id;
257 th = th->next)
258 continue;
259
260 if (th->next != NULL)
261 {
262 thread_info *here = th->next;
263 th->next = here->next;
264 CloseHandle (here->h);
265 free (here);
266 }
267}
268
269static void
270check (BOOL ok, const char *file, int line)
271{
272 if (!ok)
273 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
274}
275
276static void
277do_child_fetch_inferior_registers (int r)
278{
279 if (r >= 0)
280 supply_register (r, ((char *) &current_thread->context) + mappings[r]);
281 else
282 {
283 for (r = 0; r < NUM_REGS; r++)
284 do_child_fetch_inferior_registers (r);
285 }
286}
287
288static void
289child_fetch_inferior_registers (int r)
290{
291 current_thread = thread_rec (inferior_pid, TRUE);
292 do_child_fetch_inferior_registers (r);
293}
294
295static void
296do_child_store_inferior_registers (int r)
297{
298 if (r >= 0)
299 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
300 else
301 {
302 for (r = 0; r < NUM_REGS; r++)
303 do_child_store_inferior_registers (r);
304 }
305}
306
307/* Store a new register value into the current thread context */
308static void
309child_store_inferior_registers (int r)
310{
311 current_thread = thread_rec (inferior_pid, TRUE);
312 do_child_store_inferior_registers (r);
313}
314
315/* Wait for child to do something. Return pid of child, or -1 in case
316 of error; store status through argument pointer OURSTATUS. */
317
318static int
319handle_load_dll (PTR dummy)
320{
c5aa993b 321 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c
SS
322 DWORD dll_name_ptr;
323 DWORD done;
324 char dll_buf[MAX_PATH + 1];
7be570e7 325 char *p, *dll_name = NULL;
c906108c
SS
326 struct objfile *objfile;
327 MEMORY_BASIC_INFORMATION minfo;
328
c5aa993b 329 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c
SS
330
331 /* The following code attempts to find the name of the dll by reading the
332 name from the processes memory. Unfortunately it doesn't work right.
333 Doing this the "right way" for Windows is very difficult. FIXME */
334#ifdef DOESNT_WORK
335 memset (&minfo, 0, sizeof minfo);
336 if (VirtualQueryEx (current_process_handle, (LPCVOID) event->lpBaseOfDll,
c5aa993b
JM
337 &minfo, sizeof (minfo)) && minfo.BaseAddress)
338 {
c906108c
SS
339 DWORD len;
340 IMAGE_DOS_HEADER *hmm0 = (IMAGE_DOS_HEADER *) minfo.BaseAddress;
341 HMODULE hmm = (HMODULE) (((DWORD) hmm0) + hmm0->e_lfanew);
342
343 if ((len = GetModuleFileName (hmm, dll_buf, MAX_PATH)))
344 {
345 dll_name = dll_buf;
346 dll_name[len] = '\0';
347 }
c5aa993b 348 }
c906108c
SS
349#endif
350
351 /* Attempt to read the name of the dll that was detected.
352 This is documented to work only when actively debugging
353 a program. It will not work for attached processes. */
354 if (dll_name == NULL || *dll_name == '\0')
355 {
356 int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
357 int len = 0;
358 char b[2];
359
360 ReadProcessMemory (current_process_handle,
361 (LPCVOID) event->lpImageName,
362 (char *) &dll_name_ptr,
363 sizeof (dll_name_ptr), &done);
364
365 /* See if we could read the address of a string, and that the
c5aa993b 366 address isn't null. */
c906108c
SS
367
368 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
369 return 1;
370
371 do
372 {
373 ReadProcessMemory (current_process_handle,
374 (LPCVOID) (dll_name_ptr + len * size),
375 &b,
376 size,
377 &done);
378 len++;
379 }
380 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
381
382 dll_name = alloca (len);
383
384 if (event->fUnicode)
385 {
386 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
387 ReadProcessMemory (current_process_handle,
388 (LPCVOID) dll_name_ptr,
389 unicode_dll_name,
390 len * sizeof (WCHAR),
391 &done);
392
393 WideCharToMultiByte (CP_ACP, 0,
394 unicode_dll_name, len,
395 dll_name, len, 0, 0);
396 }
397 else
398 {
399 ReadProcessMemory (current_process_handle,
400 (LPCVOID) dll_name_ptr,
401 dll_name,
402 len,
403 &done);
404 }
405 }
406
407 if (!dll_name)
408 return 1;
409
410 while ((p = strchr (dll_name, '\\')))
411 *p = '/';
412
c906108c
SS
413 /* The symbols in a dll are offset by 0x1000, which is the
414 the offset from 0 of the first byte in an image - because
415 of the file header and the section alignment.
416
417 FIXME: Is this the real reason that we need the 0x1000 ? */
418
419 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
420 symbol_file_add (dll_name, 0, (int) event->lpBaseOfDll + 0x1000, 0, 0, 0, 0, 1);
421 printf_unfiltered ("\n");
422
c906108c
SS
423 return 1;
424}
425
426/* Handle DEBUG_STRING output from child process.
427 Cygwin prepends its messages with a "cygwin:". Interpret this as
428 a Cygwin signal. Otherwise just print the string as a warning. */
429static int
430handle_output_debug_string (struct target_waitstatus *ourstatus)
431{
432 char *s;
433 int gotasig = FALSE;
434
435 if (!target_read_string
c5aa993b 436 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
437 || !s || !*s)
438 return gotasig;
439
c5aa993b 440 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1))
c906108c
SS
441 {
442 warning (s);
443 }
444 else
445 {
446 char *p;
c5aa993b 447 /*last_sig = */ strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
7a292a7a
SS
448 gotasig = target_signal_from_host (last_sig);
449 ourstatus->value.sig = gotasig;
450 if (gotasig)
c906108c
SS
451 ourstatus->kind = TARGET_WAITKIND_STOPPED;
452 }
453
454 free (s);
455 return gotasig;
456}
457
458static int
459handle_exception (struct target_waitstatus *ourstatus)
460{
461 int i;
462 int done = 0;
463 thread_info *th;
464
465 ourstatus->kind = TARGET_WAITKIND_STOPPED;
466
467 /* Record the context of the current thread */
468 th = thread_rec (current_event.dwThreadId, -1);
469
470 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
471 {
472 case EXCEPTION_ACCESS_VIOLATION:
473 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
c5aa993b 474 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
475 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
476 break;
477 case STATUS_STACK_OVERFLOW:
478 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
c5aa993b 479 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
480 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
481 break;
482 case EXCEPTION_BREAKPOINT:
483 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
c5aa993b 484 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
485 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
486 break;
487 case DBG_CONTROL_C:
488 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
c5aa993b 489 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
490 ourstatus->value.sig = TARGET_SIGNAL_INT;
491 /* User typed CTRL-C. Continue with this status */
492 last_sig = SIGINT; /* FIXME - should check pass state */
493 break;
494 case EXCEPTION_SINGLE_STEP:
495 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
c5aa993b 496 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
c906108c
SS
497 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
498 break;
499 default:
500 /* This may be a structured exception handling exception. In
c5aa993b
JM
501 that case, we want to let the program try to handle it, and
502 only break if we see the exception a second time. */
c906108c
SS
503 if (current_event.u.Exception.dwFirstChance)
504 return 0;
505
506 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
c5aa993b
JM
507 current_event.u.Exception.ExceptionRecord.ExceptionCode,
508 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
509 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
510 break;
511 }
512 exception_count++;
513 return 1;
514}
515
516/* Resume all artificially suspended threads if we are continuing
517 execution */
518static BOOL
519child_continue (DWORD continue_status, int id)
520{
521 int i;
522 thread_info *th;
523 BOOL res;
524
525 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
526 current_event.dwProcessId, current_event.dwThreadId));
7a292a7a
SS
527 res = ContinueDebugEvent (current_event.dwProcessId,
528 current_event.dwThreadId,
529 continue_status);
530 if (res)
c5aa993b 531 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
532 if (((id == -1) || (id == th->id)) && th->suspend_count)
533 {
534 for (i = 0; i < th->suspend_count; i++)
535 (void) ResumeThread (th->h);
536 th->suspend_count = 0;
537 }
538
539 return res;
540}
541
542static int
543child_wait (int pid, struct target_waitstatus *ourstatus)
544{
545 /* We loop when we get a non-standard exception rather than return
546 with a SPURIOUS because resume can try and step or modify things,
547 which needs a current_thread->h. But some of these exceptions mark
548 the birth or death of threads, which mean that the current thread
549 isn't necessarily what you think it is. */
550
551 while (1)
552 {
553 DWORD continue_status;
7a292a7a 554 BOOL debug_event = WaitForDebugEvent (&current_event, 20);
c906108c
SS
555 char *p;
556 thread_info *th;
557 int sig;
558
7a292a7a 559 if (debug_event)
c906108c 560 {
7a292a7a
SS
561 event_count++;
562
563 continue_status = DBG_CONTINUE;
564
565 switch (current_event.dwDebugEventCode)
566 {
567 case CREATE_THREAD_DEBUG_EVENT:
568 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
c5aa993b 569 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
570 "CREATE_THREAD_DEBUG_EVENT"));
571 /* Record the existence of this thread */
572 child_add_thread (current_event.dwThreadId,
573 current_event.u.CreateThread.hThread);
574 if (info_verbose)
575 printf_unfiltered ("[New %s]\n",
c5aa993b 576 target_pid_to_str (current_event.dwThreadId));
7a292a7a
SS
577 break;
578
579 case EXIT_THREAD_DEBUG_EVENT:
580 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 581 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
582 "EXIT_THREAD_DEBUG_EVENT"));
583 child_delete_thread (current_event.dwThreadId);
584 break;
585
586 case CREATE_PROCESS_DEBUG_EVENT:
587 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 588 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
589 "CREATE_PROCESS_DEBUG_EVENT"));
590 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
591
592 main_thread_id = inferior_pid = current_event.dwThreadId;
593 /* Add the main thread */
594 current_thread = child_add_thread (inferior_pid,
c5aa993b 595 current_event.u.CreateProcessInfo.hThread);
7a292a7a
SS
596 break;
597
598 case EXIT_PROCESS_DEBUG_EVENT:
599 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 600 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
601 "EXIT_PROCESS_DEBUG_EVENT"));
602 ourstatus->kind = TARGET_WAITKIND_EXITED;
603 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
604 CloseHandle (current_process_handle);
605 return current_event.dwProcessId;
606 break;
607
608 case LOAD_DLL_DEBUG_EVENT:
609 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 610 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
611 "LOAD_DLL_DEBUG_EVENT"));
612 catch_errors (handle_load_dll, NULL, "", RETURN_MASK_ALL);
c5aa993b 613 registers_changed (); /* mark all regs invalid */
7a292a7a
SS
614 break;
615
616 case UNLOAD_DLL_DEBUG_EVENT:
617 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 618 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a 619 "UNLOAD_DLL_DEBUG_EVENT"));
c5aa993b 620 break; /* FIXME: don't know what to do here */
7a292a7a
SS
621
622 case EXCEPTION_DEBUG_EVENT:
623 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 624 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
625 "EXCEPTION_DEBUG_EVENT"));
626 if (handle_exception (ourstatus))
627 return current_event.dwThreadId;
628 continue_status = DBG_EXCEPTION_NOT_HANDLED;
629 break;
630
c5aa993b 631 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
7a292a7a 632 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
c5aa993b 633 current_event.dwProcessId, current_event.dwThreadId,
7a292a7a
SS
634 "OUTPUT_DEBUG_STRING_EVENT"));
635 if (handle_output_debug_string (ourstatus))
636 return main_thread_id;
637 break;
638 default:
639 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
640 current_event.dwProcessId,
641 current_event.dwThreadId);
642 printf_unfiltered (" unknown event code %d\n",
643 current_event.dwDebugEventCode);
644 break;
645 }
646
647 CHECK (child_continue (continue_status, -1));
c906108c 648 }
7a292a7a
SS
649 else
650 {
651 int detach = 0;
c906108c 652
7a292a7a
SS
653 if (ui_loop_hook != NULL)
654 detach = ui_loop_hook (0);
655
656 if (detach)
657 child_kill_inferior ();
658 }
c906108c
SS
659 }
660}
661
662/* Attach to process PID, then initialize for debugging it. */
663
664static void
665child_attach (args, from_tty)
666 char *args;
667 int from_tty;
668{
669 BOOL ok;
670
671 if (!args)
672 error_no_arg ("process-id to attach");
673
674 current_event.dwProcessId = strtoul (args, 0, 0);
675
676 ok = DebugActiveProcess (current_event.dwProcessId);
677
678 if (!ok)
679 error ("Can't attach to process.");
680
681 exception_count = 0;
682 event_count = 0;
683
684 if (from_tty)
685 {
686 char *exec_file = (char *) get_exec_file (0);
687
688 if (exec_file)
689 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
690 target_pid_to_str (current_event.dwProcessId));
691 else
692 printf_unfiltered ("Attaching to %s\n",
693 target_pid_to_str (current_event.dwProcessId));
694
695 gdb_flush (gdb_stdout);
696 }
697
698 push_target (&child_ops);
699}
700
701static void
702child_detach (args, from_tty)
703 char *args;
704 int from_tty;
705{
706 if (from_tty)
707 {
708 char *exec_file = get_exec_file (0);
709 if (exec_file == 0)
710 exec_file = "";
711 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
712 target_pid_to_str (inferior_pid));
713 gdb_flush (gdb_stdout);
714 }
715 inferior_pid = 0;
716 unpush_target (&child_ops);
717}
718
719/* Print status information about what we're accessing. */
720
721static void
722child_files_info (ignore)
723 struct target_ops *ignore;
724{
725 printf_unfiltered ("\tUsing the running image of %s %s.\n",
726 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
727}
728
729/* ARGSUSED */
730static void
731child_open (arg, from_tty)
732 char *arg;
733 int from_tty;
734{
735 error ("Use the \"run\" command to start a Unix child process.");
736}
737
738/* Start an inferior win32 child process and sets inferior_pid to its pid.
739 EXEC_FILE is the file to run.
740 ALLARGS is a string containing the arguments to the program.
741 ENV is the environment vector to pass. Errors reported with error(). */
742
743static void
744child_create_inferior (exec_file, allargs, env)
745 char *exec_file;
746 char *allargs;
747 char **env;
748{
749 char real_path[MAXPATHLEN];
750 char *winenv;
751 char *temp;
c5aa993b 752 int envlen;
c906108c
SS
753 int i;
754
755 STARTUPINFO si;
756 PROCESS_INFORMATION pi;
757 struct target_waitstatus dummy;
758 BOOL ret;
759 DWORD flags;
760 char *args;
761
762 if (!exec_file)
763 {
764 error ("No executable specified, use `target exec'.\n");
765 }
766
767 memset (&si, 0, sizeof (si));
768 si.cb = sizeof (si);
769
770 cygwin32_conv_to_win32_path (exec_file, real_path);
771
772 flags = DEBUG_ONLY_THIS_PROCESS;
773
774 if (new_group)
775 flags |= CREATE_NEW_PROCESS_GROUP;
776
777 if (new_console)
778 flags |= CREATE_NEW_CONSOLE;
779
780 args = alloca (strlen (real_path) + strlen (allargs) + 2);
781
782 strcpy (args, real_path);
783
784 strcat (args, " ");
785 strcat (args, allargs);
786
787 /* Prepare the environment vars for CreateProcess. */
788 {
789 /* This code use to assume all env vars were file names and would
790 translate them all to win32 style. That obviously doesn't work in the
791 general case. The current rule is that we only translate PATH.
792 We need to handle PATH because we're about to call CreateProcess and
793 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
794 in both posix and win32 environments. cygwin.dll will change it back
795 to posix style if necessary. */
796
797 static const char *conv_path_names[] =
c5aa993b
JM
798 {
799 "PATH=",
800 0
801 };
c906108c
SS
802
803 /* CreateProcess takes the environment list as a null terminated set of
804 strings (i.e. two nulls terminate the list). */
805
806 /* Get total size for env strings. */
807 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
808 {
809 int j, len;
810
811 for (j = 0; conv_path_names[j]; j++)
812 {
813 len = strlen (conv_path_names[j]);
814 if (strncmp (conv_path_names[j], env[i], len) == 0)
815 {
816 if (cygwin32_posix_path_list_p (env[i] + len))
817 envlen += len
818 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
819 else
820 envlen += strlen (env[i]) + 1;
821 break;
822 }
823 }
824 if (conv_path_names[j] == NULL)
825 envlen += strlen (env[i]) + 1;
826 }
827
828 winenv = alloca (envlen + 1);
829
830 /* Copy env strings into new buffer. */
831 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
832 {
833 int j, len;
834
835 for (j = 0; conv_path_names[j]; j++)
836 {
837 len = strlen (conv_path_names[j]);
838 if (strncmp (conv_path_names[j], env[i], len) == 0)
839 {
840 if (cygwin32_posix_path_list_p (env[i] + len))
841 {
842 memcpy (temp, env[i], len);
843 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
844 }
845 else
846 strcpy (temp, env[i]);
847 break;
848 }
849 }
850 if (conv_path_names[j] == NULL)
851 strcpy (temp, env[i]);
852
853 temp += strlen (temp) + 1;
854 }
855
856 /* Final nil string to terminate new env. */
857 *temp = 0;
858 }
859
860 ret = CreateProcess (0,
c5aa993b 861 args, /* command line */
c906108c
SS
862 NULL, /* Security */
863 NULL, /* thread */
864 TRUE, /* inherit handles */
865 flags, /* start flags */
866 winenv,
867 NULL, /* current directory */
868 &si,
869 &pi);
870 if (!ret)
c5aa993b 871 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
c906108c
SS
872
873 exception_count = 0;
874 event_count = 0;
875
876 current_process_handle = pi.hProcess;
877 current_event.dwProcessId = pi.dwProcessId;
878 memset (&current_event, 0, sizeof (current_event));
879 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
880 push_target (&child_ops);
881 child_init_thread_list ();
882 init_wait_for_inferior ();
883 clear_proceed_status ();
884 target_terminal_init ();
885 target_terminal_inferior ();
886
887 /* Ignore the first trap */
888 child_wait (inferior_pid, &dummy);
889
890 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
891}
892
893static void
894child_mourn_inferior ()
895{
896 (void) child_continue (DBG_CONTINUE, -1);
897 unpush_target (&child_ops);
898 generic_mourn_inferior ();
899}
900
901/* Send a SIGINT to the process group. This acts just like the user typed a
902 ^C on the controlling terminal. */
903
904static void
905child_stop ()
906{
907 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
908 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
c5aa993b 909 registers_changed (); /* refresh register state */
c906108c
SS
910}
911
912int
913child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
914 int write, struct target_ops *target)
915{
916 DWORD done;
917 if (write)
918 {
919 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
920 len, memaddr));
921 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
922 len, &done);
923 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
924 }
925 else
926 {
927 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
928 len, memaddr));
929 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
930 &done);
931 }
932 return done;
933}
934
935void
936child_kill_inferior (void)
937{
938 CHECK (TerminateProcess (current_process_handle, 0));
939
940 for (;;)
941 {
942 if (!child_continue (DBG_CONTINUE, -1))
943 break;
944 if (!WaitForDebugEvent (&current_event, INFINITE))
945 break;
946 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
947 break;
948 }
949
950 CHECK (CloseHandle (current_process_handle));
951
952 /* this may fail in an attached process so don't check. */
953 (void) CloseHandle (current_thread->h);
c5aa993b 954 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
955}
956
957void
958child_resume (int pid, int step, enum target_signal sig)
959{
960 int i;
961 thread_info *th;
962 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
c5aa993b 963 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
c906108c
SS
964
965 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
966 pid, step, sig));
967
968 /* Get context for currently selected thread */
969 th = thread_rec (current_event.dwThreadId, FALSE);
970 if (step)
971 {
972#ifdef i386
973 /* Single step by setting t bit */
974 child_fetch_inferior_registers (PS_REGNUM);
975 th->context.EFlags |= FLAG_TRACE_BIT;
976#endif
977 }
978
979 if (th->context.ContextFlags)
980 {
981 CHECK (SetThreadContext (th->h, &th->context));
982 th->context.ContextFlags = 0;
983 }
984
985 /* Allow continuing with the same signal that interrupted us.
986 Otherwise complain. */
987 if (sig && sig != last_sig)
988 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
989
990 last_sig = 0;
991 child_continue (continue_status, pid);
992}
993
994static void
995child_prepare_to_store ()
996{
997 /* Do nothing, since we can store individual regs */
998}
999
1000static int
1001child_can_run ()
1002{
1003 return 1;
1004}
1005
1006static void
1007child_close ()
1008{
1009 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1010}
1011
c5aa993b 1012struct target_ops child_ops;
c906108c 1013
c5aa993b
JM
1014static void
1015init_child_ops (void)
c906108c 1016{
c5aa993b
JM
1017 child_ops.to_shortname = "child";
1018 child_ops.to_longname = "Win32 child process";
1019 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1020 child_ops.to_open = child_open;
1021 child_ops.to_close = child_close;
1022 child_ops.to_attach = child_attach;
1023 child_ops.to_detach = child_detach;
1024 child_ops.to_resume = child_resume;
1025 child_ops.to_wait = child_wait;
1026 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1027 child_ops.to_store_registers = child_store_inferior_registers;
1028 child_ops.to_prepare_to_store = child_prepare_to_store;
1029 child_ops.to_xfer_memory = child_xfer_memory;
1030 child_ops.to_files_info = child_files_info;
1031 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1032 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1033 child_ops.to_terminal_init = terminal_init_inferior;
1034 child_ops.to_terminal_inferior = terminal_inferior;
1035 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1036 child_ops.to_terminal_ours = terminal_ours;
1037 child_ops.to_terminal_info = child_terminal_info;
1038 child_ops.to_kill = child_kill_inferior;
1039 child_ops.to_load = 0;
1040 child_ops.to_lookup_symbol = 0;
1041 child_ops.to_create_inferior = child_create_inferior;
1042 child_ops.to_mourn_inferior = child_mourn_inferior;
1043 child_ops.to_can_run = child_can_run;
1044 child_ops.to_notice_signals = 0;
1045 child_ops.to_thread_alive = win32_child_thread_alive;
1046 child_ops.to_stop = child_stop;
1047 child_ops.to_stratum = process_stratum;
1048 child_ops.DONT_USE = 0;
1049 child_ops.to_has_all_memory = 1;
1050 child_ops.to_has_memory = 1;
1051 child_ops.to_has_stack = 1;
1052 child_ops.to_has_registers = 1;
1053 child_ops.to_has_execution = 1;
1054 child_ops.to_sections = 0;
1055 child_ops.to_sections_end = 0;
1056 child_ops.to_magic = OPS_MAGIC;
c906108c
SS
1057}
1058
1059void
1060_initialize_inftarg ()
1061{
1062 struct cmd_list_element *c;
c5aa993b 1063 init_child_ops ();
c906108c
SS
1064
1065 add_show_from_set
1066 (add_set_cmd ("new-console", class_support, var_boolean,
1067 (char *) &new_console,
1068 "Set creation of new console when creating child process.",
1069 &setlist),
1070 &showlist);
1071
1072 add_show_from_set
1073 (add_set_cmd ("new-group", class_support, var_boolean,
1074 (char *) &new_group,
1075 "Set creation of new group when creating child process.",
1076 &setlist),
1077 &showlist);
1078
1079 add_show_from_set
1080 (add_set_cmd ("debugexec", class_support, var_boolean,
1081 (char *) &debug_exec,
1082 "Set whether to display execution in child process.",
1083 &setlist),
1084 &showlist);
1085
1086 add_show_from_set
1087 (add_set_cmd ("debugevents", class_support, var_boolean,
1088 (char *) &debug_events,
1089 "Set whether to display kernel events in child process.",
1090 &setlist),
1091 &showlist);
1092
1093 add_show_from_set
1094 (add_set_cmd ("debugmemory", class_support, var_boolean,
1095 (char *) &debug_memory,
1096 "Set whether to display memory accesses in child process.",
1097 &setlist),
1098 &showlist);
1099
1100 add_show_from_set
1101 (add_set_cmd ("debugexceptions", class_support, var_boolean,
1102 (char *) &debug_exceptions,
c5aa993b 1103 "Set whether to display kernel exceptions in child process.",
c906108c
SS
1104 &setlist),
1105 &showlist);
1106
1107 add_target (&child_ops);
1108}
1109
1110/* Determine if the thread referenced by "pid" is alive
1111 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1112 it means that the pid has died. Otherwise it is assumed to be alive. */
1113static int
1114win32_child_thread_alive (int pid)
1115{
c5aa993b
JM
1116 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1117 FALSE : TRUE;
c906108c
SS
1118}
1119
1120/* Convert pid to printable format. */
1121char *
1122cygwin_pid_to_str (int pid)
1123{
1124 static char buf[80];
1125 if (pid == current_event.dwProcessId)
1126 sprintf (buf, "process %d", pid);
1127 else
1128 sprintf (buf, "thread %d.0x%x", current_event.dwProcessId, pid);
1129 return buf;
1130}
This page took 0.077823 seconds and 4 git commands to generate.