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.
5 This file is part of GDB.
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.
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.
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, Boston, MA 02111-1307, USA.
24 /* We assume we're being built with and will be used for cygwin. */
27 #include "frame.h" /* required by inferior.h */
34 #include <sys/types.h>
40 #else /* other WIN32 compiler */
47 #include "gdb_string.h"
48 #include "gdbthread.h"
50 #include <sys/param.h>
53 /* The string sent by cygwin when it processes a signal.
54 FIXME: This should be in a cygwin include file. */
55 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
57 #define CHECK(x) check (x, __FILE__,__LINE__)
58 #define DEBUG_EXEC(x) if (debug_exec) printf x
59 #define DEBUG_EVENTS(x) if (debug_events) printf x
60 #define DEBUG_MEM(x) if (debug_memory) printf x
61 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
63 /* Forward declaration */
64 extern struct target_ops child_ops;
66 static void child_stop PARAMS ((void));
67 static int child_thread_alive PARAMS ((int));
69 static int last_sig = 0; /* Set if a signal was received from the
72 /* Thread information structure used to track information that is
73 not available in gdb's thread structure. */
74 typedef struct thread_info_struct
76 struct thread_info_struct *next;
84 static thread_info thread_head = {NULL};
86 /* The process and thread handles for the above context. */
88 static DEBUG_EVENT current_event; /* The current debug event from
90 static HANDLE current_process_handle; /* Currently executing process */
91 static thread_info *current_thread; /* Info on currently selected thread */
92 static DWORD main_thread_id; /* Thread ID of the main thread */
94 /* Counts of things. */
95 static int exception_count = 0;
96 static int event_count = 0;
99 static int new_console = 0;
100 static int new_group = 0;
101 static int debug_exec = 0; /* show execution */
102 static int debug_events = 0; /* show events from kernel */
103 static int debug_memory = 0; /* show target memory accesses */
104 static int debug_exceptions = 0; /* show target exceptions */
106 /* This vector maps GDB's idea of a register's number into an address
107 in the win32 exception context vector.
109 It also contains the bit mask needed to load the register in question.
111 One day we could read a reg, we could inspect the context we
112 already have loaded, if it doesn't have the bit set that we need,
113 we read that set of registers in using GetThreadContext. If the
114 context already contains what we need, we just unpack it. Then to
115 write a register, first we have to ensure that the context contains
116 the other regs of the group, and then we copy the info in and set
119 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
120 static const int mappings[] =
131 context_offset(EFlags),
132 context_offset(SegCs),
133 context_offset(SegSs),
134 context_offset(SegDs),
135 context_offset(SegEs),
136 context_offset(SegFs),
137 context_offset(SegGs),
138 context_offset(FloatSave.RegisterArea[0 * 10]),
139 context_offset(FloatSave.RegisterArea[1 * 10]),
140 context_offset(FloatSave.RegisterArea[2 * 10]),
141 context_offset(FloatSave.RegisterArea[3 * 10]),
142 context_offset(FloatSave.RegisterArea[4 * 10]),
143 context_offset(FloatSave.RegisterArea[5 * 10]),
144 context_offset(FloatSave.RegisterArea[6 * 10]),
145 context_offset(FloatSave.RegisterArea[7 * 10]),
148 /* This vector maps the target's idea of an exception (extracted
149 from the DEBUG_EVENT structure) to GDB's idea. */
151 struct xlate_exception
154 enum target_signal us;
157 static const struct xlate_exception
160 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
161 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
162 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
163 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
164 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
167 /* Find a thread record given a thread id.
168 If get_context then also retrieve the context for this
171 thread_rec (DWORD id, int get_context)
175 for (th = &thread_head; (th = th->next) != NULL; )
178 if (!th->suspend_count && get_context)
181 th->suspend_count = SuspendThread (th->h) + 1;
182 else if (get_context < 0)
183 th->suspend_count = -1;
185 th->context.ContextFlags = CONTEXT_DEBUGGER;
186 GetThreadContext (th->h, &th->context);
194 /* Add a thread to the thread list */
196 child_add_thread(DWORD id, HANDLE h)
200 if ((th = thread_rec (id, FALSE)))
203 th = (thread_info *) xmalloc (sizeof (*th));
204 memset(th, 0, sizeof (*th));
207 th->next = thread_head.next;
208 thread_head.next = th;
213 /* Clear out any old thread list and reintialize it to a
216 child_init_thread_list ()
218 thread_info *th = &thread_head;
220 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
222 while (th->next != NULL)
224 thread_info *here = th->next;
225 th->next = here->next;
226 (void) CloseHandle (here->h);
231 /* Delete a thread from the list of threads */
233 child_delete_thread (DWORD id)
238 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
241 for (th = &thread_head;
242 th->next != NULL && th->next->id != id;
246 if (th->next != NULL)
248 thread_info *here = th->next;
249 th->next = here->next;
250 CloseHandle (here->h);
256 check (BOOL ok, const char *file, int line)
259 printf_filtered ("error return %s:%d was %d\n", file, line, GetLastError ());
263 do_child_fetch_inferior_registers (int r)
266 supply_register (r, ((char *) ¤t_thread->context) + mappings[r]);
269 for (r = 0; r < NUM_REGS; r++)
270 do_child_fetch_inferior_registers (r);
275 child_fetch_inferior_registers (int r)
277 current_thread = thread_rec (inferior_pid, TRUE);
278 do_child_fetch_inferior_registers (r);
282 do_child_store_inferior_registers (int r)
285 read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
288 for (r = 0; r < NUM_REGS; r++)
289 do_child_store_inferior_registers (r);
293 /* Store a new register value into the current thread context */
295 child_store_inferior_registers (int r)
297 current_thread = thread_rec (inferior_pid, TRUE);
298 do_child_store_inferior_registers (r);
301 /* Wait for child to do something. Return pid of child, or -1 in case
302 of error; store status through argument pointer OURSTATUS. */
305 handle_load_dll (char *dummy)
307 LOAD_DLL_DEBUG_INFO * event = ¤t_event.u.LoadDll;
310 char dll_buf[MAX_PATH + 1];
311 char *p, *dll_name = NULL, *dll_basename;
312 struct objfile *objfile;
313 MEMORY_BASIC_INFORMATION minfo;
315 dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
317 /* The following code attempts to find the name of the dll by reading the
318 name from the processes memory. Unfortunately it doesn't work right.
319 Doing this the "right way" for Windows is very difficult. FIXME */
321 memset (&minfo, 0, sizeof minfo);
322 if (VirtualQueryEx (current_process_handle, (LPCVOID) event->lpBaseOfDll,
323 &minfo, sizeof(minfo)) && minfo.BaseAddress) {
325 IMAGE_DOS_HEADER *hmm0 = (IMAGE_DOS_HEADER *) minfo.BaseAddress;
326 HMODULE hmm = (HMODULE) (((DWORD) hmm0) + hmm0->e_lfanew);
328 if ((len = GetModuleFileName (hmm, dll_buf, MAX_PATH)))
331 dll_name[len] = '\0';
336 /* Attempt to read the name of the dll that was detected.
337 This is documented to work only when actively debugging
338 a program. It will not work for attached processes. */
339 if (dll_name == NULL || *dll_name == '\0')
341 int size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
345 ReadProcessMemory (current_process_handle,
346 (LPCVOID) event->lpImageName,
347 (char *) &dll_name_ptr,
348 sizeof (dll_name_ptr), &done);
350 /* See if we could read the address of a string, and that the
351 address isn't null. */
353 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
358 ReadProcessMemory (current_process_handle,
359 (LPCVOID) (dll_name_ptr + len * size),
365 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
367 dll_name = alloca (len);
371 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
372 ReadProcessMemory (current_process_handle,
373 (LPCVOID) dll_name_ptr,
375 len * sizeof (WCHAR),
378 WideCharToMultiByte (CP_ACP, 0,
379 unicode_dll_name, len,
380 dll_name, len, 0, 0);
384 ReadProcessMemory (current_process_handle,
385 (LPCVOID) dll_name_ptr,
395 while ((p = strchr (dll_name, '\\')))
398 /* FIXME!! It would be nice to define one symbol which pointed to the
399 front of the dll if we can't find any symbols. */
401 if (!(dll_basename = strrchr(dll_name, '/')))
402 dll_basename = dll_name;
406 ALL_OBJFILES(objfile)
408 char *objfile_basename;
409 objfile_basename = strrchr(objfile->name, '/');
411 if (objfile_basename &&
412 strcmp(dll_basename, objfile_basename + 1) == 0)
414 printf_unfiltered ("%x:%s (symbols previously loaded)\n",
415 event->lpBaseOfDll, dll_name);
420 /* The symbols in a dll are offset by 0x1000, which is the
421 the offset from 0 of the first byte in an image - because
422 of the file header and the section alignment.
424 FIXME: Is this the real reason that we need the 0x1000 ? */
426 printf_unfiltered ("%x:%s", event->lpBaseOfDll, dll_name);
427 symbol_file_add (dll_name, 0, (int) event->lpBaseOfDll + 0x1000, 0, 0, 0);
428 printf_unfiltered ("\n");
434 /* Handle DEBUG_STRING output from child process.
435 Cygwin prepends its messages with a "cygwin:". Interpret this as
436 a Cygwin signal. Otherwise just print the string as a warning. */
438 handle_output_debug_string (struct target_waitstatus *ourstatus)
443 if (!target_read_string
444 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
448 if (strncmp(s, CYGWIN_SIGNAL_STRING, sizeof(CYGWIN_SIGNAL_STRING) - 1))
455 /*last_sig = */strtol(s + sizeof(CYGWIN_SIGNAL_STRING) - 1, &p, 0);
456 if (gotasig = (ourstatus->value.sig = target_signal_from_host (last_sig)))
457 ourstatus->kind = TARGET_WAITKIND_STOPPED;
465 handle_exception (struct target_waitstatus *ourstatus)
471 ourstatus->kind = TARGET_WAITKIND_STOPPED;
473 /* Record the context of the current thread */
474 th = thread_rec (current_event.dwThreadId, -1);
476 switch (current_event.u.Exception.ExceptionRecord.ExceptionCode)
478 case EXCEPTION_ACCESS_VIOLATION:
479 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08x\n",
480 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
481 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
483 case STATUS_STACK_OVERFLOW:
484 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08x\n",
485 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
486 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
488 case EXCEPTION_BREAKPOINT:
489 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08x\n",
490 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
491 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
494 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08x\n",
495 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
496 ourstatus->value.sig = TARGET_SIGNAL_INT;
497 /* User typed CTRL-C. Continue with this status */
498 last_sig = SIGINT; /* FIXME - should check pass state */
500 case EXCEPTION_SINGLE_STEP:
501 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08x\n",
502 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
503 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
506 /* This may be a structured exception handling exception. In
507 that case, we want to let the program try to handle it, and
508 only break if we see the exception a second time. */
509 if (current_event.u.Exception.dwFirstChance)
512 printf_unfiltered ("gdb: unknown target exception 0x%08x at 0x%08x\n",
513 current_event.u.Exception.ExceptionRecord.ExceptionCode,
514 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
515 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
522 /* Resume all artificially suspended threads if we are continuing
525 child_continue (DWORD continue_status, int id)
531 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=%d, DBG_CONTINUE);\n",
532 current_event.dwProcessId, current_event.dwThreadId));
533 if (res = ContinueDebugEvent (current_event.dwProcessId,
534 current_event.dwThreadId,
536 for (th = &thread_head; (th = th->next) != NULL; )
537 if (((id == -1) || (id == th->id)) && th->suspend_count)
539 for (i = 0; i < th->suspend_count; i++)
540 (void) ResumeThread (th->h);
541 th->suspend_count = 0;
548 child_wait (int pid, struct target_waitstatus *ourstatus)
550 /* We loop when we get a non-standard exception rather than return
551 with a SPURIOUS because resume can try and step or modify things,
552 which needs a current_thread->h. But some of these exceptions mark
553 the birth or death of threads, which mean that the current thread
554 isn't necessarily what you think it is. */
558 DWORD continue_status;
559 BOOL t = WaitForDebugEvent (¤t_event, INFINITE);
566 continue_status = DBG_CONTINUE;
568 switch (current_event.dwDebugEventCode)
570 case CREATE_THREAD_DEBUG_EVENT:
571 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
572 current_event.dwProcessId, current_event.dwThreadId,
573 "CREATE_THREAD_DEBUG_EVENT"));
574 /* Record the existence of this thread */
575 child_add_thread (current_event.dwThreadId,
576 current_event.u.CreateThread.hThread);
578 printf_unfiltered ("[New %s]\n",
579 target_pid_to_str (current_event.dwThreadId));
582 case EXIT_THREAD_DEBUG_EVENT:
583 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
584 current_event.dwProcessId, current_event.dwThreadId,
585 "EXIT_THREAD_DEBUG_EVENT"));
586 child_delete_thread (current_event.dwThreadId);
589 case CREATE_PROCESS_DEBUG_EVENT:
590 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
591 current_event.dwProcessId, current_event.dwThreadId,
592 "CREATE_PROCESS_DEBUG_EVENT"));
593 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
595 main_thread_id = inferior_pid = current_event.dwThreadId;
596 /* Add the main thread */
597 current_thread = child_add_thread (inferior_pid,
598 current_event.u.CreateProcessInfo.hThread);
601 case EXIT_PROCESS_DEBUG_EVENT:
602 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
603 current_event.dwProcessId, current_event.dwThreadId,
604 "EXIT_PROCESS_DEBUG_EVENT"));
605 ourstatus->kind = TARGET_WAITKIND_EXITED;
606 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
607 CloseHandle (current_process_handle);
608 return current_event.dwProcessId;
611 case LOAD_DLL_DEBUG_EVENT:
612 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
613 current_event.dwProcessId, current_event.dwThreadId,
614 "LOAD_DLL_DEBUG_EVENT"));
615 catch_errors (handle_load_dll, NULL, "", RETURN_MASK_ALL);
616 registers_changed(); /* mark all regs invalid */
619 case UNLOAD_DLL_DEBUG_EVENT:
620 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
621 current_event.dwProcessId, current_event.dwThreadId,
622 "UNLOAD_DLL_DEBUG_EVENT"));
623 break; /* FIXME: don't know what to do here */
625 case EXCEPTION_DEBUG_EVENT:
626 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
627 current_event.dwProcessId, current_event.dwThreadId,
628 "EXCEPTION_DEBUG_EVENT"));
629 if (handle_exception (ourstatus))
630 return current_event.dwThreadId;
631 continue_status = DBG_EXCEPTION_NOT_HANDLED;
634 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
635 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
636 current_event.dwProcessId, current_event.dwThreadId,
637 "OUTPUT_DEBUG_STRING_EVENT"));
638 if (handle_output_debug_string (ourstatus))
639 return main_thread_id;
642 printf_unfiltered ("gdb: kernel event for pid=%d tid=%d\n",
643 current_event.dwProcessId,
644 current_event.dwThreadId);
645 printf_unfiltered (" unknown event code %d\n",
646 current_event.dwDebugEventCode);
650 CHECK (child_continue (continue_status, -1));
654 /* Attach to process PID, then initialize for debugging it. */
657 child_attach (args, from_tty)
664 error_no_arg ("process-id to attach");
666 current_event.dwProcessId = strtoul (args, 0, 0);
668 ok = DebugActiveProcess (current_event.dwProcessId);
671 error ("Can't attach to process.");
678 char *exec_file = (char *) get_exec_file (0);
681 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
682 target_pid_to_str (current_event.dwProcessId));
684 printf_unfiltered ("Attaching to %s\n",
685 target_pid_to_str (current_event.dwProcessId));
687 gdb_flush (gdb_stdout);
690 push_target (&child_ops);
694 child_detach (args, from_tty)
700 char *exec_file = get_exec_file (0);
703 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
704 target_pid_to_str (inferior_pid));
705 gdb_flush (gdb_stdout);
708 unpush_target (&child_ops);
711 /* Print status information about what we're accessing. */
714 child_files_info (ignore)
715 struct target_ops *ignore;
717 printf_unfiltered ("\tUsing the running image of %s %s.\n",
718 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
723 child_open (arg, from_tty)
727 error ("Use the \"run\" command to start a Unix child process.");
730 /* Start an inferior win32 child process and sets inferior_pid to its pid.
731 EXEC_FILE is the file to run.
732 ALLARGS is a string containing the arguments to the program.
733 ENV is the environment vector to pass. Errors reported with error(). */
736 child_create_inferior (exec_file, allargs, env)
741 char real_path[MAXPATHLEN];
748 PROCESS_INFORMATION pi;
749 struct target_waitstatus dummy;
756 error ("No executable specified, use `target exec'.\n");
759 memset (&si, 0, sizeof (si));
762 cygwin32_conv_to_win32_path (exec_file, real_path);
764 flags = DEBUG_ONLY_THIS_PROCESS;
767 flags |= CREATE_NEW_PROCESS_GROUP;
770 flags |= CREATE_NEW_CONSOLE;
772 args = alloca (strlen (real_path) + strlen (allargs) + 2);
774 strcpy (args, real_path);
777 strcat (args, allargs);
779 /* Prepare the environment vars for CreateProcess. */
781 /* This code use to assume all env vars were file names and would
782 translate them all to win32 style. That obviously doesn't work in the
783 general case. The current rule is that we only translate PATH.
784 We need to handle PATH because we're about to call CreateProcess and
785 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
786 in both posix and win32 environments. cygwin.dll will change it back
787 to posix style if necessary. */
789 static const char *conv_path_names[] =
795 /* CreateProcess takes the environment list as a null terminated set of
796 strings (i.e. two nulls terminate the list). */
798 /* Get total size for env strings. */
799 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
803 for (j = 0; conv_path_names[j]; j++)
805 len = strlen (conv_path_names[j]);
806 if (strncmp (conv_path_names[j], env[i], len) == 0)
808 if (cygwin32_posix_path_list_p (env[i] + len))
810 + cygwin32_posix_to_win32_path_list_buf_size (env[i] + len);
812 envlen += strlen (env[i]) + 1;
816 if (conv_path_names[j] == NULL)
817 envlen += strlen (env[i]) + 1;
820 winenv = alloca (envlen + 1);
822 /* Copy env strings into new buffer. */
823 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
827 for (j = 0; conv_path_names[j]; j++)
829 len = strlen (conv_path_names[j]);
830 if (strncmp (conv_path_names[j], env[i], len) == 0)
832 if (cygwin32_posix_path_list_p (env[i] + len))
834 memcpy (temp, env[i], len);
835 cygwin32_posix_to_win32_path_list (env[i] + len, temp + len);
838 strcpy (temp, env[i]);
842 if (conv_path_names[j] == NULL)
843 strcpy (temp, env[i]);
845 temp += strlen (temp) + 1;
848 /* Final nil string to terminate new env. */
852 ret = CreateProcess (0,
853 args, /* command line */
856 TRUE, /* inherit handles */
857 flags, /* start flags */
859 NULL, /* current directory */
863 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError());
868 current_process_handle = pi.hProcess;
869 current_event.dwProcessId = pi.dwProcessId;
870 memset (¤t_event, 0, sizeof (current_event));
871 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
872 push_target (&child_ops);
873 child_init_thread_list ();
874 init_wait_for_inferior ();
875 clear_proceed_status ();
876 target_terminal_init ();
877 target_terminal_inferior ();
879 /* Ignore the first trap */
880 child_wait (inferior_pid, &dummy);
882 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
886 child_mourn_inferior ()
888 (void) child_continue (DBG_CONTINUE, -1);
889 unpush_target (&child_ops);
890 generic_mourn_inferior ();
893 /* Send a SIGINT to the process group. This acts just like the user typed a
894 ^C on the controlling terminal. */
899 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
900 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0));
901 registers_changed(); /* refresh register state */
905 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
906 int write, struct target_ops *target)
911 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08x\n",
913 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
915 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
919 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08x\n",
921 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
928 child_kill_inferior (void)
930 CHECK (TerminateProcess (current_process_handle, 0));
934 if (!child_continue (DBG_CONTINUE, -1))
936 if (!WaitForDebugEvent (¤t_event, INFINITE))
938 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
942 CHECK (CloseHandle (current_process_handle));
944 /* this may fail in an attached process so don't check. */
945 (void) CloseHandle (current_thread->h);
946 target_mourn_inferior(); /* or just child_mourn_inferior? */
950 child_resume (int pid, int step, enum target_signal sig)
954 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
955 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
957 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
960 /* Get context for currently selected thread */
961 th = thread_rec (current_event.dwThreadId, FALSE);
965 /* Single step by setting t bit */
966 child_fetch_inferior_registers (PS_REGNUM);
967 th->context.EFlags |= FLAG_TRACE_BIT;
971 if (th->context.ContextFlags)
973 CHECK (SetThreadContext (th->h, &th->context));
974 th->context.ContextFlags = 0;
977 /* Allow continuing with the same signal that interrupted us.
978 Otherwise complain. */
979 if (sig && sig != last_sig)
980 fprintf_unfiltered (gdb_stderr, "Can't send signals to the child. signal %d\n", sig);
983 child_continue (continue_status, pid);
987 child_prepare_to_store ()
989 /* Do nothing, since we can store individual regs */
1001 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1004 struct target_ops child_ops ;
1006 static void init_child_ops(void)
1008 child_ops.to_shortname = "child";
1009 child_ops.to_longname = "Win32 child process";
1010 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1011 child_ops.to_open = child_open;
1012 child_ops.to_close = child_close;
1013 child_ops.to_attach = child_attach;
1014 child_ops.to_detach = child_detach;
1015 child_ops.to_resume = child_resume;
1016 child_ops.to_wait = child_wait;
1017 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1018 child_ops.to_store_registers = child_store_inferior_registers;
1019 child_ops.to_prepare_to_store = child_prepare_to_store;
1020 child_ops.to_xfer_memory = child_xfer_memory;
1021 child_ops.to_files_info = child_files_info;
1022 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1023 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1024 child_ops.to_terminal_init = terminal_init_inferior;
1025 child_ops.to_terminal_inferior = terminal_inferior;
1026 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1027 child_ops.to_terminal_ours = terminal_ours;
1028 child_ops.to_terminal_info = child_terminal_info;
1029 child_ops.to_kill = child_kill_inferior;
1030 child_ops.to_load = 0;
1031 child_ops.to_lookup_symbol = 0;
1032 child_ops.to_create_inferior = child_create_inferior;
1033 child_ops.to_mourn_inferior = child_mourn_inferior;
1034 child_ops.to_can_run = child_can_run;
1035 child_ops.to_notice_signals = 0;
1036 child_ops.to_thread_alive = child_thread_alive;
1037 child_ops.to_stop = child_stop;
1038 child_ops.to_stratum = process_stratum;
1039 child_ops.DONT_USE = 0;
1040 child_ops.to_has_all_memory = 1;
1041 child_ops.to_has_memory = 1;
1042 child_ops.to_has_stack = 1;
1043 child_ops.to_has_registers = 1;
1044 child_ops.to_has_execution = 1;
1045 child_ops.to_sections = 0;
1046 child_ops.to_sections_end = 0;
1047 child_ops.to_magic = OPS_MAGIC;
1051 _initialize_inftarg ()
1053 struct cmd_list_element *c;
1057 (add_set_cmd ("new-console", class_support, var_boolean,
1058 (char *) &new_console,
1059 "Set creation of new console when creating child process.",
1064 (add_set_cmd ("new-group", class_support, var_boolean,
1065 (char *) &new_group,
1066 "Set creation of new group when creating child process.",
1071 (add_set_cmd ("debugexec", class_support, var_boolean,
1072 (char *) &debug_exec,
1073 "Set whether to display execution in child process.",
1078 (add_set_cmd ("debugevents", class_support, var_boolean,
1079 (char *) &debug_events,
1080 "Set whether to display kernel events in child process.",
1085 (add_set_cmd ("debugmemory", class_support, var_boolean,
1086 (char *) &debug_memory,
1087 "Set whether to display memory accesses in child process.",
1092 (add_set_cmd ("debugexceptions", class_support, var_boolean,
1093 (char *) &debug_exceptions,
1094 "Set whether to display kernel exceptions in child process.",
1098 add_target (&child_ops);
1101 /* Determine if the thread referenced by "pid" is alive
1102 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1103 it means that the pid has died. Otherwise it is assumed to be alive. */
1105 child_thread_alive (int pid)
1107 return WaitForSingleObject(thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1111 /* Convert pid to printable format. */
1113 cygwin_pid_to_str (int pid)
1115 static char buf[80];
1116 if (pid == current_event.dwProcessId)
1117 sprintf (buf, "process %d", pid);
1119 sprintf (buf, "thread %d.0x%x", current_event.dwProcessId, pid);