1 /* Target-vector operations for controlling win32 child processes, for GDB.
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions, A Red Hat Company.
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,
20 Boston, MA 02111-1307, USA.
23 /* by Steve Chamberlain, sac@cygnus.com */
25 /* We assume we're being built with and will be used for cygwin. */
28 #include "frame.h" /* required by inferior.h */
34 #include <sys/types.h>
39 #include <sys/cygwin.h>
44 #include "gdb_string.h"
45 #include "gdbthread.h"
47 #include <sys/param.h>
50 /* The ui's event loop. */
51 extern int (*ui_loop_hook) PARAMS ((int signo));
53 /* If we're not using the old Cygwin header file set, define the
54 following which never should have been in the generic Win32 API
55 headers in the first place since they were our own invention... */
56 #ifndef _GNU_H_WINDOWS_H
57 #define FLAG_TRACE_BIT 0x100
58 #define CONTEXT_DEBUGGER (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
61 #define FIRST_EXCEPTION 0xffffffff
63 /* The string sent by cygwin when it processes a signal.
64 FIXME: This should be in a cygwin include file. */
65 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
67 #define CHECK(x) check (x, __FILE__,__LINE__)
68 #define DEBUG_EXEC(x) if (debug_exec) printf x
69 #define DEBUG_EVENTS(x) if (debug_events) printf x
70 #define DEBUG_MEM(x) if (debug_memory) printf x
71 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
73 /* Forward declaration */
74 extern struct target_ops child_ops;
76 static void child_stop (void);
77 static int win32_child_thread_alive (int);
78 void child_kill_inferior (void);
80 static int last_sig = 0; /* Set if a signal was received from the
82 /* Thread information structure used to track information that is
83 not available in gdb's thread structure. */
84 typedef struct thread_info_struct
86 struct thread_info_struct *next;
95 static thread_info thread_head;
97 /* The process and thread handles for the above context. */
99 static DEBUG_EVENT current_event; /* The current debug event from
101 static HANDLE current_process_handle; /* Currently executing process */
102 static thread_info *current_thread; /* Info on currently selected thread */
103 static DWORD main_thread_id; /* Thread ID of the main thread */
105 /* Counts of things. */
106 static int exception_count = 0;
107 static int event_count = 0;
110 static int new_console = 0;
111 static int new_group = 1;
112 static int debug_exec = 0; /* show execution */
113 static int debug_events = 0; /* show events from kernel */
114 static int debug_memory = 0; /* show target memory accesses */
115 static int debug_exceptions = 0; /* show target exceptions */
117 /* This vector maps GDB's idea of a register's number into an address
118 in the win32 exception context vector.
120 It also contains the bit mask needed to load the register in question.
122 One day we could read a reg, we could inspect the context we
123 already have loaded, if it doesn't have the bit set that we need,
124 we read that set of registers in using GetThreadContext. If the
125 context already contains what we need, we just unpack it. Then to
126 write a register, first we have to ensure that the context contains
127 the other regs of the group, and then we copy the info in and set
130 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
131 static const int mappings[] =
133 context_offset (Eax),
134 context_offset (Ecx),
135 context_offset (Edx),
136 context_offset (Ebx),
137 context_offset (Esp),
138 context_offset (Ebp),
139 context_offset (Esi),
140 context_offset (Edi),
141 context_offset (Eip),
142 context_offset (EFlags),
143 context_offset (SegCs),
144 context_offset (SegSs),
145 context_offset (SegDs),
146 context_offset (SegEs),
147 context_offset (SegFs),
148 context_offset (SegGs),
149 context_offset (FloatSave.RegisterArea[0 * 10]),
150 context_offset (FloatSave.RegisterArea[1 * 10]),
151 context_offset (FloatSave.RegisterArea[2 * 10]),
152 context_offset (FloatSave.RegisterArea[3 * 10]),
153 context_offset (FloatSave.RegisterArea[4 * 10]),
154 context_offset (FloatSave.RegisterArea[5 * 10]),
155 context_offset (FloatSave.RegisterArea[6 * 10]),
156 context_offset (FloatSave.RegisterArea[7 * 10]),
157 context_offset (FloatSave.ControlWord),
158 context_offset (FloatSave.StatusWord),
159 context_offset (FloatSave.TagWord),
160 context_offset (FloatSave.ErrorSelector),
161 context_offset (FloatSave.ErrorOffset),
162 context_offset (FloatSave.DataSelector),
163 context_offset (FloatSave.DataOffset),
164 context_offset (FloatSave.ErrorSelector)
167 #undef context_offset
169 /* This vector maps the target's idea of an exception (extracted
170 from the DEBUG_EVENT structure) to GDB's idea. */
172 struct xlate_exception
175 enum target_signal us;
178 static const struct xlate_exception
181 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
182 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
183 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
184 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
185 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
188 /* Find a thread record given a thread id.
189 If get_context then also retrieve the context for this
192 thread_rec (DWORD id, int get_context)
196 for (th = &thread_head; (th = th->next) != NULL;)
199 if (!th->suspend_count && get_context)
201 if (get_context > 0 && id != current_event.dwThreadId)
202 th->suspend_count = SuspendThread (th->h) + 1;
203 else if (get_context < 0)
204 th->suspend_count = -1;
206 th->context.ContextFlags = CONTEXT_DEBUGGER;
207 GetThreadContext (th->h, &th->context);
215 /* Add a thread to the thread list */
217 child_add_thread (DWORD id, HANDLE h)
221 if ((th = thread_rec (id, FALSE)))
224 th = (thread_info *) xmalloc (sizeof (*th));
225 memset (th, 0, sizeof (*th));
228 th->next = thread_head.next;
229 thread_head.next = th;
234 /* Clear out any old thread list and reintialize it to a
237 child_init_thread_list ()
239 thread_info *th = &thread_head;
241 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
243 while (th->next != NULL)
245 thread_info *here = th->next;
246 th->next = here->next;
247 (void) CloseHandle (here->h);
252 /* Delete a thread from the list of threads */
254 child_delete_thread (DWORD id)
259 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
262 for (th = &thread_head;
263 th->next != NULL && th->next->id != id;
267 if (th->next != NULL)
269 thread_info *here = th->next;
270 th->next = here->next;
271 CloseHandle (here->h);
277 check (BOOL ok, const char *file, int line)
280 printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
284 do_child_fetch_inferior_registers (int r)
286 char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
290 l = *((long *)context_offset) & 0xffff;
291 supply_register (r, (char *) &l);
293 else if (r == FOP_REGNUM)
295 l = (*((long *)context_offset) >> 16) & ((1 << 11) - 1);
296 supply_register (r, (char *) &l);
299 supply_register (r, context_offset);
302 for (r = 0; r < NUM_REGS; r++)
303 do_child_fetch_inferior_registers (r);
308 child_fetch_inferior_registers (int r)
310 current_thread = thread_rec (inferior_pid, TRUE);
311 do_child_fetch_inferior_registers (r);
315 do_child_store_inferior_registers (int r)
318 read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
321 for (r = 0; r < NUM_REGS; r++)
322 do_child_store_inferior_registers (r);
326 /* Store a new register value into the current thread context */
328 child_store_inferior_registers (int r)
330 current_thread = thread_rec (inferior_pid, TRUE);
331 do_child_store_inferior_registers (r);
335 static int psapi_loaded = 0;
336 static HMODULE psapi_module_handle = NULL;
337 static BOOL WINAPI (*psapi_EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD)= NULL;
338 static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD)= NULL;
339 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD)= NULL;
341 int psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
346 HMODULE dh_buf [ 1 ];
347 HMODULE* DllHandle = dh_buf;
352 psapi_EnumProcessModules == NULL ||
353 psapi_GetModuleInformation == NULL ||
354 psapi_GetModuleFileNameExA == NULL)
356 if (psapi_loaded)goto failed;
358 psapi_module_handle = LoadLibrary ("psapi.dll");
359 if (!psapi_module_handle)
361 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
364 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules" );
365 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
366 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
367 "GetModuleFileNameExA");
368 if (psapi_EnumProcessModules == NULL ||
369 psapi_GetModuleInformation == NULL ||
370 psapi_GetModuleFileNameExA == NULL)
375 ok = (*psapi_EnumProcessModules) (current_process_handle,
380 if (!ok || !cbNeeded)
383 DllHandle = (HMODULE*) alloca (cbNeeded);
387 ok = (*psapi_EnumProcessModules) (current_process_handle,
394 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
396 if (!(*psapi_GetModuleInformation) (current_process_handle,
400 error ("Can't get module info");
402 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
407 error ("Error getting dll name: %u\n", GetLastError ());
409 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
414 dll_name_ret[0] = '\0';
418 struct safe_symbol_file_add_args
422 struct section_addr_info *addrs;
429 safe_symbol_file_add_stub (void *argv)
431 #define p ((struct safe_symbol_file_add_args *)argv)
432 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
438 safe_symbol_file_add_cleanup (void *gdb_stderrv)
440 ui_file_delete (gdb_stderr);
441 gdb_stderr = (struct ui_file *)gdb_stderrv;
444 static struct objfile *
445 safe_symbol_file_add (char *name, int from_tty,
446 struct section_addr_info *addrs,
447 int mainline, int flags)
450 struct safe_symbol_file_add_args p;
451 struct cleanup *cleanup;
453 cleanup = make_cleanup (safe_symbol_file_add_cleanup, gdb_stderr);
455 gdb_stderr = ui_file_new ();
457 p.from_tty = from_tty;
459 p.mainline = mainline;
461 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
463 do_cleanups (cleanup);
467 /* Wait for child to do something. Return pid of child, or -1 in case
468 of error; store status through argument pointer OURSTATUS. */
471 handle_load_dll (PTR dummy ATTRIBUTE_UNUSED)
473 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
476 char dll_buf[MAX_PATH + 1];
477 char *p, *dll_name = NULL;
478 struct section_addr_info section_addrs;
480 memset (§ion_addrs, 0, sizeof (section_addrs));
481 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
483 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
484 dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
488 /* Attempt to read the name of the dll that was detected.
489 This is documented to work only when actively debugging
490 a program. It will not work for attached processes. */
491 if (dll_name == NULL || *dll_name == '\0')
493 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
497 ReadProcessMemory (current_process_handle,
498 (LPCVOID) event->lpImageName,
499 (char *) &dll_name_ptr,
500 sizeof (dll_name_ptr), &done);
502 /* See if we could read the address of a string, and that the
503 address isn't null. */
505 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
510 ReadProcessMemory (current_process_handle,
511 (LPCVOID) (dll_name_ptr + len * size),
517 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
519 dll_name = alloca (len);
523 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
524 ReadProcessMemory (current_process_handle,
525 (LPCVOID) dll_name_ptr,
527 len * sizeof (WCHAR),
530 WideCharToMultiByte (CP_ACP, 0,
531 unicode_dll_name, len,
532 dll_name, len, 0, 0);
536 ReadProcessMemory (current_process_handle,
537 (LPCVOID) dll_name_ptr,
547 (void) strlwr (dll_name);
549 while ((p = strchr (dll_name, '\\')))
552 /* The symbols in a dll are offset by 0x1000, which is the
553 the offset from 0 of the first byte in an image - because
554 of the file header and the section alignment. */
556 section_addrs.other[0].name = ".text";
557 section_addrs.other[0].addr = (int) event->lpBaseOfDll + 0x1000;
558 safe_symbol_file_add (dll_name, 0, §ion_addrs, 0, OBJF_SHARED);
559 printf_unfiltered ("%lx:%s\n", (DWORD) event->lpBaseOfDll, dll_name);
564 /* Handle DEBUG_STRING output from child process.
565 Cygwin prepends its messages with a "cygwin:". Interpret this as
566 a Cygwin signal. Otherwise just print the string as a warning. */
568 handle_output_debug_string (struct target_waitstatus *ourstatus)
573 if (!target_read_string
574 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
578 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
580 if (strncmp (s, "cYg", 3) != 0)
586 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
587 gotasig = target_signal_from_host (sig);
588 ourstatus->value.sig = gotasig;
590 ourstatus->kind = TARGET_WAITKIND_STOPPED;
598 handle_exception (struct target_waitstatus *ourstatus, int ignore_trap)
601 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
603 if (ignore_trap && code == EXCEPTION_BREAKPOINT)
606 ourstatus->kind = TARGET_WAITKIND_STOPPED;
608 /* Record the context of the current thread */
609 th = thread_rec (current_event.dwThreadId, -1);
615 case EXCEPTION_ACCESS_VIOLATION:
616 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
617 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
618 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
621 case STATUS_FLOAT_UNDERFLOW:
622 case STATUS_FLOAT_DIVIDE_BY_ZERO:
623 case STATUS_FLOAT_OVERFLOW:
624 case STATUS_INTEGER_DIVIDE_BY_ZERO:
625 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
626 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
627 ourstatus->value.sig = TARGET_SIGNAL_FPE;
630 case STATUS_STACK_OVERFLOW:
631 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
632 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
633 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
635 case EXCEPTION_BREAKPOINT:
636 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
637 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
638 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
641 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
642 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
643 ourstatus->value.sig = TARGET_SIGNAL_INT;
644 last_sig = SIGINT; /* FIXME - should check pass state */
646 case EXCEPTION_SINGLE_STEP:
647 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
648 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
649 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
651 case EXCEPTION_ILLEGAL_INSTRUCTION:
652 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
653 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
654 ourstatus->value.sig = TARGET_SIGNAL_ILL;
658 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
659 current_event.u.Exception.ExceptionRecord.ExceptionCode,
660 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
661 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
668 /* Resume all artificially suspended threads if we are continuing
671 child_continue (DWORD continue_status, int id)
677 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
678 current_event.dwProcessId, current_event.dwThreadId));
679 res = ContinueDebugEvent (current_event.dwProcessId,
680 current_event.dwThreadId,
684 for (th = &thread_head; (th = th->next) != NULL;)
685 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
687 for (i = 0; i < th->suspend_count; i++)
688 (void) ResumeThread (th->h);
689 th->suspend_count = 0;
695 /* Get the next event from the child. Return 1 if the event requires
696 handling by WFI (or whatever).
699 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus,
700 DWORD target_event_code, int *retval)
704 DWORD continue_status, event_code;
705 thread_info *th = NULL;
706 static thread_info dummy_thread_info;
709 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
713 continue_status = DBG_CONTINUE;
715 event_code = current_event.dwDebugEventCode;
716 breakout = event_code == target_event_code;
720 case CREATE_THREAD_DEBUG_EVENT:
721 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
722 (unsigned) current_event.dwProcessId,
723 (unsigned) current_event.dwThreadId,
724 "CREATE_THREAD_DEBUG_EVENT"));
725 /* Record the existence of this thread */
726 th = child_add_thread (current_event.dwThreadId,
727 current_event.u.CreateThread.hThread);
729 printf_unfiltered ("[New %s]\n",
730 target_pid_to_str (current_event.dwThreadId));
733 case EXIT_THREAD_DEBUG_EVENT:
734 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
735 (unsigned) current_event.dwProcessId,
736 (unsigned) current_event.dwThreadId,
737 "EXIT_THREAD_DEBUG_EVENT"));
738 child_delete_thread (current_event.dwThreadId);
739 th = &dummy_thread_info;
742 case CREATE_PROCESS_DEBUG_EVENT:
743 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
744 (unsigned) current_event.dwProcessId,
745 (unsigned) current_event.dwThreadId,
746 "CREATE_PROCESS_DEBUG_EVENT"));
747 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
749 main_thread_id = inferior_pid = current_event.dwThreadId;
750 /* Add the main thread */
751 th = child_add_thread (inferior_pid,
752 current_event.u.CreateProcessInfo.hThread);
755 case EXIT_PROCESS_DEBUG_EVENT:
756 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
757 (unsigned) current_event.dwProcessId,
758 (unsigned) current_event.dwThreadId,
759 "EXIT_PROCESS_DEBUG_EVENT"));
760 ourstatus->kind = TARGET_WAITKIND_EXITED;
761 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
762 CloseHandle (current_process_handle);
763 *retval = current_event.dwProcessId;
767 case LOAD_DLL_DEBUG_EVENT:
768 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
769 (unsigned) current_event.dwProcessId,
770 (unsigned) current_event.dwThreadId,
771 "LOAD_DLL_DEBUG_EVENT"));
772 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
773 registers_changed (); /* mark all regs invalid */
776 case UNLOAD_DLL_DEBUG_EVENT:
777 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
778 (unsigned) current_event.dwProcessId,
779 (unsigned) current_event.dwThreadId,
780 "UNLOAD_DLL_DEBUG_EVENT"));
781 break; /* FIXME: don't know what to do here */
783 case EXCEPTION_DEBUG_EVENT:
784 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
785 (unsigned) current_event.dwProcessId,
786 (unsigned) current_event.dwThreadId,
787 "EXCEPTION_DEBUG_EVENT"));
788 if (handle_exception (ourstatus, target_event_code == FIRST_EXCEPTION))
789 *retval = current_event.dwThreadId;
794 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
795 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
796 (unsigned) current_event.dwProcessId,
797 (unsigned) current_event.dwThreadId,
798 "OUTPUT_DEBUG_STRING_EVENT"));
799 handle_output_debug_string ( ourstatus);
802 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
803 (DWORD) current_event.dwProcessId,
804 (DWORD) current_event.dwThreadId);
805 printf_unfiltered (" unknown event code %ld\n",
806 current_event.dwDebugEventCode);
811 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
813 CHECK (child_continue (continue_status, -1));
819 /* Wait for interesting events to occur in the target process. */
821 child_wait (int pid, struct target_waitstatus *ourstatus)
825 /* We loop when we get a non-standard exception rather than return
826 with a SPURIOUS because resume can try and step or modify things,
827 which needs a current_thread->h. But some of these exceptions mark
828 the birth or death of threads, which mean that the current thread
829 isn't necessarily what you think it is. */
832 if (get_child_debug_event (pid, ourstatus, EXCEPTION_DEBUG_EVENT, &retval))
838 if (ui_loop_hook != NULL)
839 detach = ui_loop_hook (0);
842 child_kill_inferior ();
846 /* Attach to process PID, then initialize for debugging it. */
849 child_attach (args, from_tty)
856 error_no_arg ("process-id to attach");
858 current_event.dwProcessId = strtoul (args, 0, 0);
860 ok = DebugActiveProcess (current_event.dwProcessId);
863 error ("Can't attach to process.");
870 char *exec_file = (char *) get_exec_file (0);
873 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
874 target_pid_to_str (current_event.dwProcessId));
876 printf_unfiltered ("Attaching to %s\n",
877 target_pid_to_str (current_event.dwProcessId));
879 gdb_flush (gdb_stdout);
882 push_target (&child_ops);
886 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
890 char *exec_file = get_exec_file (0);
893 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
894 target_pid_to_str (inferior_pid));
895 gdb_flush (gdb_stdout);
898 unpush_target (&child_ops);
901 /* Print status information about what we're accessing. */
904 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
906 printf_unfiltered ("\tUsing the running image of %s %s.\n",
907 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
912 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
914 error ("Use the \"run\" command to start a Unix child process.");
917 /* Start an inferior win32 child process and sets inferior_pid to its pid.
918 EXEC_FILE is the file to run.
919 ALLARGS is a string containing the arguments to the program.
920 ENV is the environment vector to pass. Errors reported with error(). */
923 child_create_inferior (exec_file, allargs, env)
928 char real_path[MAXPATHLEN];
934 PROCESS_INFORMATION pi;
935 struct target_waitstatus dummy;
942 error ("No executable specified, use `target exec'.\n");
945 memset (&si, 0, sizeof (si));
948 cygwin_conv_to_win32_path (exec_file, real_path);
950 flags = DEBUG_ONLY_THIS_PROCESS;
953 flags |= CREATE_NEW_PROCESS_GROUP;
956 flags |= CREATE_NEW_CONSOLE;
958 args = alloca (strlen (real_path) + strlen (allargs) + 2);
960 strcpy (args, real_path);
963 strcat (args, allargs);
965 /* Prepare the environment vars for CreateProcess. */
967 /* This code use to assume all env vars were file names and would
968 translate them all to win32 style. That obviously doesn't work in the
969 general case. The current rule is that we only translate PATH.
970 We need to handle PATH because we're about to call CreateProcess and
971 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
972 in both posix and win32 environments. cygwin.dll will change it back
973 to posix style if necessary. */
975 static const char *conv_path_names[] =
981 /* CreateProcess takes the environment list as a null terminated set of
982 strings (i.e. two nulls terminate the list). */
984 /* Get total size for env strings. */
985 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
989 for (j = 0; conv_path_names[j]; j++)
991 len = strlen (conv_path_names[j]);
992 if (strncmp (conv_path_names[j], env[i], len) == 0)
994 if (cygwin_posix_path_list_p (env[i] + len))
996 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
998 envlen += strlen (env[i]) + 1;
1002 if (conv_path_names[j] == NULL)
1003 envlen += strlen (env[i]) + 1;
1006 winenv = alloca (envlen + 1);
1008 /* Copy env strings into new buffer. */
1009 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1013 for (j = 0; conv_path_names[j]; j++)
1015 len = strlen (conv_path_names[j]);
1016 if (strncmp (conv_path_names[j], env[i], len) == 0)
1018 if (cygwin_posix_path_list_p (env[i] + len))
1020 memcpy (temp, env[i], len);
1021 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1024 strcpy (temp, env[i]);
1028 if (conv_path_names[j] == NULL)
1029 strcpy (temp, env[i]);
1031 temp += strlen (temp) + 1;
1034 /* Final nil string to terminate new env. */
1038 ret = CreateProcess (0,
1039 args, /* command line */
1040 NULL, /* Security */
1042 TRUE, /* inherit handles */
1043 flags, /* start flags */
1045 NULL, /* current directory */
1049 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1051 exception_count = 0;
1054 current_process_handle = pi.hProcess;
1055 current_event.dwProcessId = pi.dwProcessId;
1056 memset (¤t_event, 0, sizeof (current_event));
1057 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1058 push_target (&child_ops);
1059 child_init_thread_list ();
1060 init_wait_for_inferior ();
1061 clear_proceed_status ();
1062 target_terminal_init ();
1063 target_terminal_inferior ();
1066 /* Run until process and threads are loaded */
1067 while (!get_child_debug_event (inferior_pid, &dummy,
1068 FIRST_EXCEPTION, &ret))
1071 /* child_continue (DBG_CONTINUE, -1);*/
1072 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1076 child_mourn_inferior ()
1078 (void) child_continue (DBG_CONTINUE, -1);
1079 unpush_target (&child_ops);
1080 generic_mourn_inferior ();
1083 /* Send a SIGINT to the process group. This acts just like the user typed a
1084 ^C on the controlling terminal. */
1089 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1090 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1091 registers_changed (); /* refresh register state */
1095 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1096 int write, struct target_ops *target ATTRIBUTE_UNUSED)
1101 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1102 len, (DWORD) memaddr));
1103 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1105 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1109 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1110 len, (DWORD) memaddr));
1111 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1118 child_kill_inferior (void)
1120 CHECK (TerminateProcess (current_process_handle, 0));
1124 if (!child_continue (DBG_CONTINUE, -1))
1126 if (!WaitForDebugEvent (¤t_event, INFINITE))
1128 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1132 CHECK (CloseHandle (current_process_handle));
1134 /* this may fail in an attached process so don't check. */
1135 (void) CloseHandle (current_thread->h);
1136 target_mourn_inferior (); /* or just child_mourn_inferior? */
1140 child_resume (int pid, int step, enum target_signal sig)
1143 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1144 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1148 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1151 /* Get context for currently selected thread */
1152 th = thread_rec (current_event.dwThreadId, FALSE);
1156 /* Single step by setting t bit */
1157 child_fetch_inferior_registers (PS_REGNUM);
1158 th->context.EFlags |= FLAG_TRACE_BIT;
1162 if (th->context.ContextFlags)
1164 CHECK (SetThreadContext (th->h, &th->context));
1165 th->context.ContextFlags = 0;
1168 /* Allow continuing with the same signal that interrupted us.
1169 Otherwise complain. */
1171 child_continue (continue_status, pid);
1175 child_prepare_to_store ()
1177 /* Do nothing, since we can store individual regs */
1189 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1192 struct target_ops child_ops;
1195 init_child_ops (void)
1197 child_ops.to_shortname = "child";
1198 child_ops.to_longname = "Win32 child process";
1199 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1200 child_ops.to_open = child_open;
1201 child_ops.to_close = child_close;
1202 child_ops.to_attach = child_attach;
1203 child_ops.to_detach = child_detach;
1204 child_ops.to_resume = child_resume;
1205 child_ops.to_wait = child_wait;
1206 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1207 child_ops.to_store_registers = child_store_inferior_registers;
1208 child_ops.to_prepare_to_store = child_prepare_to_store;
1209 child_ops.to_xfer_memory = child_xfer_memory;
1210 child_ops.to_files_info = child_files_info;
1211 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1212 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1213 child_ops.to_terminal_init = terminal_init_inferior;
1214 child_ops.to_terminal_inferior = terminal_inferior;
1215 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1216 child_ops.to_terminal_ours = terminal_ours;
1217 child_ops.to_terminal_info = child_terminal_info;
1218 child_ops.to_kill = child_kill_inferior;
1219 child_ops.to_load = 0;
1220 child_ops.to_lookup_symbol = 0;
1221 child_ops.to_create_inferior = child_create_inferior;
1222 child_ops.to_mourn_inferior = child_mourn_inferior;
1223 child_ops.to_can_run = child_can_run;
1224 child_ops.to_notice_signals = 0;
1225 child_ops.to_thread_alive = win32_child_thread_alive;
1226 child_ops.to_pid_to_str = cygwin_pid_to_str;
1227 child_ops.to_stop = child_stop;
1228 child_ops.to_stratum = process_stratum;
1229 child_ops.DONT_USE = 0;
1230 child_ops.to_has_all_memory = 1;
1231 child_ops.to_has_memory = 1;
1232 child_ops.to_has_stack = 1;
1233 child_ops.to_has_registers = 1;
1234 child_ops.to_has_execution = 1;
1235 child_ops.to_sections = 0;
1236 child_ops.to_sections_end = 0;
1237 child_ops.to_magic = OPS_MAGIC;
1241 _initialize_inftarg ()
1246 (add_set_cmd ("new-console", class_support, var_boolean,
1247 (char *) &new_console,
1248 "Set creation of new console when creating child process.",
1253 (add_set_cmd ("new-group", class_support, var_boolean,
1254 (char *) &new_group,
1255 "Set creation of new group when creating child process.",
1260 (add_set_cmd ("debugexec", class_support, var_boolean,
1261 (char *) &debug_exec,
1262 "Set whether to display execution in child process.",
1267 (add_set_cmd ("debugevents", class_support, var_boolean,
1268 (char *) &debug_events,
1269 "Set whether to display kernel events in child process.",
1274 (add_set_cmd ("debugmemory", class_support, var_boolean,
1275 (char *) &debug_memory,
1276 "Set whether to display memory accesses in child process.",
1281 (add_set_cmd ("debugexceptions", class_support, var_boolean,
1282 (char *) &debug_exceptions,
1283 "Set whether to display kernel exceptions in child process.",
1287 add_target (&child_ops);
1290 /* Determine if the thread referenced by "pid" is alive
1291 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1292 it means that the pid has died. Otherwise it is assumed to be alive. */
1294 win32_child_thread_alive (int pid)
1296 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1300 /* Convert pid to printable format. */
1302 cygwin_pid_to_str (int pid)
1304 static char buf[80];
1305 if ((DWORD) pid == current_event.dwProcessId)
1306 sprintf (buf, "process %d", pid);
1308 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);