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.
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) (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 /* The string sent by cygwin when it processes a signal.
62 FIXME: This should be in a cygwin include file. */
63 #define CYGWIN_SIGNAL_STRING "cygwin: signal"
65 #define CHECK(x) check (x, __FILE__,__LINE__)
66 #define DEBUG_EXEC(x) if (debug_exec) printf x
67 #define DEBUG_EVENTS(x) if (debug_events) printf x
68 #define DEBUG_MEM(x) if (debug_memory) printf x
69 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
71 /* Forward declaration */
72 extern struct target_ops child_ops;
74 static void child_stop (void);
75 static int win32_child_thread_alive (int);
76 void child_kill_inferior (void);
78 static int last_sig = 0; /* Set if a signal was received from the
80 /* Thread information structure used to track information that is
81 not available in gdb's thread structure. */
82 typedef struct thread_info_struct
84 struct thread_info_struct *next;
93 static thread_info thread_head;
95 /* The process and thread handles for the above context. */
97 static DEBUG_EVENT current_event; /* The current debug event from
99 static HANDLE current_process_handle; /* Currently executing process */
100 static thread_info *current_thread; /* Info on currently selected thread */
101 static DWORD main_thread_id; /* Thread ID of the main thread */
103 /* Counts of things. */
104 static int exception_count = 0;
105 static int event_count = 0;
108 static int new_console = 0;
109 static int new_group = 1;
110 static int debug_exec = 0; /* show execution */
111 static int debug_events = 0; /* show events from kernel */
112 static int debug_memory = 0; /* show target memory accesses */
113 static int debug_exceptions = 0; /* show target exceptions */
115 /* This vector maps GDB's idea of a register's number into an address
116 in the win32 exception context vector.
118 It also contains the bit mask needed to load the register in question.
120 One day we could read a reg, we could inspect the context we
121 already have loaded, if it doesn't have the bit set that we need,
122 we read that set of registers in using GetThreadContext. If the
123 context already contains what we need, we just unpack it. Then to
124 write a register, first we have to ensure that the context contains
125 the other regs of the group, and then we copy the info in and set
128 #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
129 static const int mappings[] =
131 context_offset (Eax),
132 context_offset (Ecx),
133 context_offset (Edx),
134 context_offset (Ebx),
135 context_offset (Esp),
136 context_offset (Ebp),
137 context_offset (Esi),
138 context_offset (Edi),
139 context_offset (Eip),
140 context_offset (EFlags),
141 context_offset (SegCs),
142 context_offset (SegSs),
143 context_offset (SegDs),
144 context_offset (SegEs),
145 context_offset (SegFs),
146 context_offset (SegGs),
147 context_offset (FloatSave.RegisterArea[0 * 10]),
148 context_offset (FloatSave.RegisterArea[1 * 10]),
149 context_offset (FloatSave.RegisterArea[2 * 10]),
150 context_offset (FloatSave.RegisterArea[3 * 10]),
151 context_offset (FloatSave.RegisterArea[4 * 10]),
152 context_offset (FloatSave.RegisterArea[5 * 10]),
153 context_offset (FloatSave.RegisterArea[6 * 10]),
154 context_offset (FloatSave.RegisterArea[7 * 10]),
155 context_offset (FloatSave.ControlWord),
156 context_offset (FloatSave.StatusWord),
157 context_offset (FloatSave.TagWord),
158 context_offset (FloatSave.ErrorSelector),
159 context_offset (FloatSave.ErrorOffset),
160 context_offset (FloatSave.DataSelector),
161 context_offset (FloatSave.DataOffset),
162 context_offset (FloatSave.ErrorSelector)
165 #undef context_offset
167 /* This vector maps the target's idea of an exception (extracted
168 from the DEBUG_EVENT structure) to GDB's idea. */
170 struct xlate_exception
173 enum target_signal us;
176 static const struct xlate_exception
179 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
180 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
181 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
182 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
183 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
186 /* Find a thread record given a thread id.
187 If get_context then also retrieve the context for this
190 thread_rec (DWORD id, int get_context)
194 for (th = &thread_head; (th = th->next) != NULL;)
197 if (!th->suspend_count && get_context)
199 if (get_context > 0 && id != current_event.dwThreadId)
200 th->suspend_count = SuspendThread (th->h) + 1;
201 else if (get_context < 0)
202 th->suspend_count = -1;
204 th->context.ContextFlags = CONTEXT_DEBUGGER;
205 GetThreadContext (th->h, &th->context);
213 /* Add a thread to the thread list */
215 child_add_thread (DWORD id, HANDLE h)
219 if ((th = thread_rec (id, FALSE)))
222 th = (thread_info *) xmalloc (sizeof (*th));
223 memset (th, 0, sizeof (*th));
226 th->next = thread_head.next;
227 thread_head.next = th;
232 /* Clear out any old thread list and reintialize it to a
235 child_init_thread_list ()
237 thread_info *th = &thread_head;
239 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
241 while (th->next != NULL)
243 thread_info *here = th->next;
244 th->next = here->next;
245 (void) CloseHandle (here->h);
250 /* Delete a thread from the list of threads */
252 child_delete_thread (DWORD id)
257 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (id));
260 for (th = &thread_head;
261 th->next != NULL && th->next->id != id;
265 if (th->next != NULL)
267 thread_info *here = th->next;
268 th->next = here->next;
269 CloseHandle (here->h);
275 check (BOOL ok, const char *file, int line)
278 printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
282 do_child_fetch_inferior_registers (int r)
284 char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
288 l = *((long *)context_offset) & 0xffff;
289 supply_register (r, (char *) &l);
291 else if (r == FOP_REGNUM)
293 l = (*((long *)context_offset) >> 16) & ((1 << 11) - 1);
294 supply_register (r, (char *) &l);
297 supply_register (r, context_offset);
300 for (r = 0; r < NUM_REGS; r++)
301 do_child_fetch_inferior_registers (r);
306 child_fetch_inferior_registers (int r)
308 current_thread = thread_rec (inferior_pid, TRUE);
309 do_child_fetch_inferior_registers (r);
313 do_child_store_inferior_registers (int r)
316 read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
319 for (r = 0; r < NUM_REGS; r++)
320 do_child_store_inferior_registers (r);
324 /* Store a new register value into the current thread context */
326 child_store_inferior_registers (int r)
328 current_thread = thread_rec (inferior_pid, TRUE);
329 do_child_store_inferior_registers (r);
333 static int psapi_loaded = 0;
334 static HMODULE psapi_module_handle = NULL;
335 static BOOL WINAPI (*psapi_EnumProcessModules)(HANDLE, HMODULE*, DWORD, LPDWORD)= NULL;
336 static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD)= NULL;
337 static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD)= NULL;
339 int psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
344 HMODULE dh_buf [ 1 ];
345 HMODULE* DllHandle = dh_buf;
350 psapi_EnumProcessModules == NULL ||
351 psapi_GetModuleInformation == NULL ||
352 psapi_GetModuleFileNameExA == NULL)
354 if (psapi_loaded)goto failed;
356 psapi_module_handle = LoadLibrary ("psapi.dll");
357 if (!psapi_module_handle)
359 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ());*/
362 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules" );
363 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
364 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
365 "GetModuleFileNameExA");
366 if (psapi_EnumProcessModules == NULL ||
367 psapi_GetModuleInformation == NULL ||
368 psapi_GetModuleFileNameExA == NULL)
373 ok = (*psapi_EnumProcessModules) (current_process_handle,
378 if (!ok || !cbNeeded)
381 DllHandle = (HMODULE*) alloca (cbNeeded);
385 ok = (*psapi_EnumProcessModules) (current_process_handle,
392 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
394 if (!(*psapi_GetModuleInformation) (current_process_handle,
398 error ("Can't get module info");
400 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
405 error ("Error getting dll name: %u\n", GetLastError ());
407 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
412 dll_name_ret[0] = '\0';
416 /* Encapsulate the information required in a call to
417 symbol_file_add_args */
418 struct safe_symbol_file_add_args
422 struct section_addr_info *addrs;
425 struct ui_file *err, *out;
429 /* Call symbol_file_add with stderr redirected. We don't care if there
432 safe_symbol_file_add_stub (void *argv)
434 #define p ((struct safe_symbol_file_add_args *)argv)
435 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
440 /* Restore gdb's stderr after calling symbol_file_add */
442 safe_symbol_file_add_cleanup (void *p)
444 #define sp ((struct safe_symbol_file_add_args *)p)
445 gdb_flush (gdb_stderr);
446 gdb_flush (gdb_stdout);
447 ui_file_delete (gdb_stderr);
448 ui_file_delete (gdb_stdout);
449 gdb_stderr = sp->err;
450 gdb_stdout = sp->err;
453 /* symbol_file_add wrapper that prevents errors from being displayed. */
454 static struct objfile *
455 safe_symbol_file_add (char *name, int from_tty,
456 struct section_addr_info *addrs,
457 int mainline, int flags)
460 struct safe_symbol_file_add_args p;
461 struct cleanup *cleanup;
463 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
467 gdb_flush (gdb_stderr);
468 gdb_flush (gdb_stdout);
469 gdb_stderr = ui_file_new ();
470 gdb_stdout = ui_file_new ();
472 p.from_tty = from_tty;
474 p.mainline = mainline;
476 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
478 do_cleanups (cleanup);
482 /* Maintain a linked list of "so" information. */
485 struct so_stuff *next, **last;
488 } solib_start, *solib_end;
490 /* Remember the maximum DLL length for printing in info dll command. */
491 int max_dll_name_len;
493 /* Wait for child to do something. Return pid of child, or -1 in case
494 of error; store status through argument pointer OURSTATUS. */
496 handle_load_dll (PTR dummy ATTRIBUTE_UNUSED)
498 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
501 char dll_buf[MAX_PATH + 1];
502 struct so_stuff *so, *solast;
503 char *dll_name = NULL;
508 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
510 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
511 dll_buf[0] = dll_buf[sizeof(dll_buf) - 1] = '\0';
515 /* Attempt to read the name of the dll that was detected.
516 This is documented to work only when actively debugging
517 a program. It will not work for attached processes. */
518 if (dll_name == NULL || *dll_name == '\0')
520 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
524 ReadProcessMemory (current_process_handle,
525 (LPCVOID) event->lpImageName,
526 (char *) &dll_name_ptr,
527 sizeof (dll_name_ptr), &done);
529 /* See if we could read the address of a string, and that the
530 address isn't null. */
532 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
537 ReadProcessMemory (current_process_handle,
538 (LPCVOID) (dll_name_ptr + len * size),
544 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
546 dll_name = alloca (len);
550 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
551 ReadProcessMemory (current_process_handle,
552 (LPCVOID) dll_name_ptr,
554 len * sizeof (WCHAR),
557 WideCharToMultiByte (CP_ACP, 0,
558 unicode_dll_name, len,
559 dll_name, len, 0, 0);
563 ReadProcessMemory (current_process_handle,
564 (LPCVOID) dll_name_ptr,
574 (void) strlwr (dll_name);
576 while ((p = strchr (dll_name, '\\')))
579 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (dll_name) + 8 + 2);
580 so->load_addr = (DWORD) event->lpBaseOfDll + 0x1000;
581 strcpy (so->name, dll_name);
583 solib_end->next = so;
587 len = strlen (dll_name);
588 if (len > max_dll_name_len)
589 max_dll_name_len = len;
594 /* Return name of last loaded DLL. */
596 child_solib_loaded_library_pathname (int pid)
598 return !solib_end || !solib_end->name[0]? NULL : solib_end->name;
601 /* Clear list of loaded DLLs. */
603 child_clear_solibs (void)
605 struct so_stuff *so, *so1 = solib_start.next;
607 while ((so = so1) != NULL)
613 solib_start.next = NULL;
614 solib_end = &solib_start;
615 max_dll_name_len = sizeof ("DLL Name") - 1;
618 /* Add DLL symbol information. */
620 child_solib_add (char *filename, int from_tty, struct target_ops *t)
622 struct section_addr_info section_addrs;
624 /* The symbols in a dll are offset by 0x1000, which is the
625 the offset from 0 of the first byte in an image - because
626 of the file header and the section alignment. */
628 if (!solib_end || !solib_end->name[0])
631 memset (§ion_addrs, 0, sizeof (section_addrs));
632 section_addrs.other[0].name = ".text";
633 section_addrs.other[0].addr = solib_end->load_addr;
634 safe_symbol_file_add (solib_end->name, 0, §ion_addrs, 0, OBJF_SHARED);
639 /* Load DLL symbol info. */
641 dll_symbol_command (char *args, int from_tty)
643 struct section_addr_info section_addrs;
648 error ("dll-symbols requires a file name");
650 safe_symbol_file_add (args, 0, NULL, 0, OBJF_SHARED);
653 /* List currently loaded DLLs. */
655 info_dll_command (char *ignore, int from_tty)
657 struct so_stuff *so = &solib_start;
662 printf ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
663 while ((so = so->next) != NULL)
664 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
669 /* Handle DEBUG_STRING output from child process.
670 Cygwin prepends its messages with a "cygwin:". Interpret this as
671 a Cygwin signal. Otherwise just print the string as a warning. */
673 handle_output_debug_string (struct target_waitstatus *ourstatus)
678 if (!target_read_string
679 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
683 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
685 if (strncmp (s, "cYg", 3) != 0)
691 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
692 gotasig = target_signal_from_host (sig);
693 ourstatus->value.sig = gotasig;
695 ourstatus->kind = TARGET_WAITKIND_STOPPED;
703 handle_exception (struct target_waitstatus *ourstatus)
706 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
708 ourstatus->kind = TARGET_WAITKIND_STOPPED;
710 /* Record the context of the current thread */
711 th = thread_rec (current_event.dwThreadId, -1);
717 case EXCEPTION_ACCESS_VIOLATION:
718 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
719 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
720 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
723 case STATUS_FLOAT_UNDERFLOW:
724 case STATUS_FLOAT_DIVIDE_BY_ZERO:
725 case STATUS_FLOAT_OVERFLOW:
726 case STATUS_INTEGER_DIVIDE_BY_ZERO:
727 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
728 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
729 ourstatus->value.sig = TARGET_SIGNAL_FPE;
732 case STATUS_STACK_OVERFLOW:
733 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
734 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
735 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
737 case EXCEPTION_BREAKPOINT:
738 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
739 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
740 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
743 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
744 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
745 ourstatus->value.sig = TARGET_SIGNAL_INT;
746 last_sig = SIGINT; /* FIXME - should check pass state */
748 case EXCEPTION_SINGLE_STEP:
749 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
750 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
751 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
753 case EXCEPTION_ILLEGAL_INSTRUCTION:
754 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
755 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
756 ourstatus->value.sig = TARGET_SIGNAL_ILL;
760 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
761 current_event.u.Exception.ExceptionRecord.ExceptionCode,
762 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
763 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
770 /* Resume all artificially suspended threads if we are continuing
773 child_continue (DWORD continue_status, int id)
779 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
780 current_event.dwProcessId, current_event.dwThreadId));
781 res = ContinueDebugEvent (current_event.dwProcessId,
782 current_event.dwThreadId,
786 for (th = &thread_head; (th = th->next) != NULL;)
787 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
789 for (i = 0; i < th->suspend_count; i++)
790 (void) ResumeThread (th->h);
791 th->suspend_count = 0;
797 /* Get the next event from the child. Return 1 if the event requires
798 handling by WFI (or whatever).
801 get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
805 DWORD continue_status, event_code;
806 thread_info *th = NULL;
807 static thread_info dummy_thread_info;
810 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
814 continue_status = DBG_CONTINUE;
816 event_code = current_event.dwDebugEventCode;
817 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
821 case CREATE_THREAD_DEBUG_EVENT:
822 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
823 (unsigned) current_event.dwProcessId,
824 (unsigned) current_event.dwThreadId,
825 "CREATE_THREAD_DEBUG_EVENT"));
826 /* Record the existence of this thread */
827 th = child_add_thread (current_event.dwThreadId,
828 current_event.u.CreateThread.hThread);
830 printf_unfiltered ("[New %s]\n",
831 target_pid_to_str (current_event.dwThreadId));
832 retval = current_event.dwThreadId;
835 case EXIT_THREAD_DEBUG_EVENT:
836 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
837 (unsigned) current_event.dwProcessId,
838 (unsigned) current_event.dwThreadId,
839 "EXIT_THREAD_DEBUG_EVENT"));
840 child_delete_thread (current_event.dwThreadId);
841 th = &dummy_thread_info;
844 case CREATE_PROCESS_DEBUG_EVENT:
845 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
846 (unsigned) current_event.dwProcessId,
847 (unsigned) current_event.dwThreadId,
848 "CREATE_PROCESS_DEBUG_EVENT"));
849 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
851 main_thread_id = inferior_pid = current_event.dwThreadId;
852 /* Add the main thread */
853 th = child_add_thread (current_event.dwProcessId,
854 current_event.u.CreateProcessInfo.hProcess);
855 th = child_add_thread (inferior_pid,
856 current_event.u.CreateProcessInfo.hThread);
857 retval = ourstatus->value.related_pid = current_event.dwProcessId;
860 case EXIT_PROCESS_DEBUG_EVENT:
861 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
862 (unsigned) current_event.dwProcessId,
863 (unsigned) current_event.dwThreadId,
864 "EXIT_PROCESS_DEBUG_EVENT"));
865 ourstatus->kind = TARGET_WAITKIND_EXITED;
866 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
867 CloseHandle (current_process_handle);
868 retval = current_event.dwProcessId;
871 case LOAD_DLL_DEBUG_EVENT:
872 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
873 (unsigned) current_event.dwProcessId,
874 (unsigned) current_event.dwThreadId,
875 "LOAD_DLL_DEBUG_EVENT"));
876 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
877 registers_changed (); /* mark all regs invalid */
878 ourstatus->kind = TARGET_WAITKIND_LOADED;
879 ourstatus->value.integer = 0;
880 retval = current_event.dwProcessId;
883 case UNLOAD_DLL_DEBUG_EVENT:
884 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
885 (unsigned) current_event.dwProcessId,
886 (unsigned) current_event.dwThreadId,
887 "UNLOAD_DLL_DEBUG_EVENT"));
888 break; /* FIXME: don't know what to do here */
890 case EXCEPTION_DEBUG_EVENT:
891 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
892 (unsigned) current_event.dwProcessId,
893 (unsigned) current_event.dwThreadId,
894 "EXCEPTION_DEBUG_EVENT"));
895 handle_exception (ourstatus);
896 retval = current_event.dwThreadId;
899 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
900 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
901 (unsigned) current_event.dwProcessId,
902 (unsigned) current_event.dwThreadId,
903 "OUTPUT_DEBUG_STRING_EVENT"));
904 if (handle_output_debug_string ( ourstatus))
905 retval = current_event.dwProcessId;
908 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
909 (DWORD) current_event.dwProcessId,
910 (DWORD) current_event.dwThreadId);
911 printf_unfiltered (" unknown event code %ld\n",
912 current_event.dwDebugEventCode);
917 CHECK (child_continue (continue_status, -1));
919 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
925 /* Wait for interesting events to occur in the target process. */
927 child_wait (int pid, struct target_waitstatus *ourstatus)
929 /* We loop when we get a non-standard exception rather than return
930 with a SPURIOUS because resume can try and step or modify things,
931 which needs a current_thread->h. But some of these exceptions mark
932 the birth or death of threads, which mean that the current thread
933 isn't necessarily what you think it is. */
937 int retval = get_child_debug_event (pid, ourstatus);
944 if (ui_loop_hook != NULL)
945 detach = ui_loop_hook (0);
948 child_kill_inferior ();
953 /* Attach to process PID, then initialize for debugging it. */
956 child_attach (args, from_tty)
963 error_no_arg ("process-id to attach");
965 current_event.dwProcessId = strtoul (args, 0, 0);
967 ok = DebugActiveProcess (current_event.dwProcessId);
970 error ("Can't attach to process.");
975 child_init_thread_list ();
976 child_clear_solibs ();
980 char *exec_file = (char *) get_exec_file (0);
983 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
984 target_pid_to_str (current_event.dwProcessId));
986 printf_unfiltered ("Attaching to %s\n",
987 target_pid_to_str (current_event.dwProcessId));
989 gdb_flush (gdb_stdout);
992 push_target (&child_ops);
996 child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
1000 char *exec_file = get_exec_file (0);
1003 printf_unfiltered ("Detaching from program: %s %s\n", exec_file,
1004 target_pid_to_str (inferior_pid));
1005 gdb_flush (gdb_stdout);
1008 unpush_target (&child_ops);
1011 /* Print status information about what we're accessing. */
1014 child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
1016 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1017 attach_flag ? "attached" : "child", target_pid_to_str (inferior_pid));
1022 child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
1024 error ("Use the \"run\" command to start a Unix child process.");
1027 /* Start an inferior win32 child process and sets inferior_pid to its pid.
1028 EXEC_FILE is the file to run.
1029 ALLARGS is a string containing the arguments to the program.
1030 ENV is the environment vector to pass. Errors reported with error(). */
1033 child_create_inferior (exec_file, allargs, env)
1038 char real_path[MAXPATHLEN];
1044 PROCESS_INFORMATION pi;
1045 struct target_waitstatus dummy;
1049 extern int stop_after_trap;
1052 error ("No executable specified, use `target exec'.\n");
1054 memset (&si, 0, sizeof (si));
1055 si.cb = sizeof (si);
1057 cygwin_conv_to_win32_path (exec_file, real_path);
1059 flags = DEBUG_ONLY_THIS_PROCESS;
1062 flags |= CREATE_NEW_PROCESS_GROUP;
1065 flags |= CREATE_NEW_CONSOLE;
1067 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1069 strcpy (args, real_path);
1072 strcat (args, allargs);
1074 /* Prepare the environment vars for CreateProcess. */
1076 /* This code use to assume all env vars were file names and would
1077 translate them all to win32 style. That obviously doesn't work in the
1078 general case. The current rule is that we only translate PATH.
1079 We need to handle PATH because we're about to call CreateProcess and
1080 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1081 in both posix and win32 environments. cygwin.dll will change it back
1082 to posix style if necessary. */
1084 static const char *conv_path_names[] =
1090 /* CreateProcess takes the environment list as a null terminated set of
1091 strings (i.e. two nulls terminate the list). */
1093 /* Get total size for env strings. */
1094 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1098 for (j = 0; conv_path_names[j]; j++)
1100 len = strlen (conv_path_names[j]);
1101 if (strncmp (conv_path_names[j], env[i], len) == 0)
1103 if (cygwin_posix_path_list_p (env[i] + len))
1105 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
1107 envlen += strlen (env[i]) + 1;
1111 if (conv_path_names[j] == NULL)
1112 envlen += strlen (env[i]) + 1;
1115 winenv = alloca (envlen + 1);
1117 /* Copy env strings into new buffer. */
1118 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1122 for (j = 0; conv_path_names[j]; j++)
1124 len = strlen (conv_path_names[j]);
1125 if (strncmp (conv_path_names[j], env[i], len) == 0)
1127 if (cygwin_posix_path_list_p (env[i] + len))
1129 memcpy (temp, env[i], len);
1130 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
1133 strcpy (temp, env[i]);
1137 if (conv_path_names[j] == NULL)
1138 strcpy (temp, env[i]);
1140 temp += strlen (temp) + 1;
1143 /* Final nil string to terminate new env. */
1147 ret = CreateProcess (0,
1148 args, /* command line */
1149 NULL, /* Security */
1151 TRUE, /* inherit handles */
1152 flags, /* start flags */
1154 NULL, /* current directory */
1158 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
1160 exception_count = 0;
1163 current_process_handle = pi.hProcess;
1164 current_event.dwProcessId = pi.dwProcessId;
1165 memset (¤t_event, 0, sizeof (current_event));
1166 inferior_pid = current_event.dwThreadId = pi.dwThreadId;
1167 push_target (&child_ops);
1168 child_init_thread_list ();
1169 child_clear_solibs ();
1170 clear_proceed_status ();
1171 init_wait_for_inferior ();
1172 target_terminal_init ();
1173 target_terminal_inferior ();
1178 stop_after_trap = 1;
1179 wait_for_inferior ();
1180 if (stop_signal != TARGET_SIGNAL_TRAP)
1181 resume (0, stop_signal);
1185 stop_after_trap = 0;
1187 /* child_continue (DBG_CONTINUE, -1);*/
1188 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
1192 child_mourn_inferior ()
1194 (void) child_continue (DBG_CONTINUE, -1);
1195 unpush_target (&child_ops);
1196 generic_mourn_inferior ();
1199 /* Send a SIGINT to the process group. This acts just like the user typed a
1200 ^C on the controlling terminal. */
1205 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1206 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1207 registers_changed (); /* refresh register state */
1211 child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
1212 int write, struct target_ops *target ATTRIBUTE_UNUSED)
1217 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1218 len, (DWORD) memaddr));
1219 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1221 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1225 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1226 len, (DWORD) memaddr));
1227 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1234 child_kill_inferior (void)
1236 CHECK (TerminateProcess (current_process_handle, 0));
1240 if (!child_continue (DBG_CONTINUE, -1))
1242 if (!WaitForDebugEvent (¤t_event, INFINITE))
1244 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1248 CHECK (CloseHandle (current_process_handle));
1250 /* this may fail in an attached process so don't check. */
1251 (void) CloseHandle (current_thread->h);
1252 target_mourn_inferior (); /* or just child_mourn_inferior? */
1256 child_resume (int pid, int step, enum target_signal sig)
1259 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
1260 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
1264 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1267 /* Get context for currently selected thread */
1268 th = thread_rec (current_event.dwThreadId, FALSE);
1273 /* Single step by setting t bit */
1274 child_fetch_inferior_registers (PS_REGNUM);
1275 th->context.EFlags |= FLAG_TRACE_BIT;
1278 if (th->context.ContextFlags)
1280 CHECK (SetThreadContext (th->h, &th->context));
1281 th->context.ContextFlags = 0;
1285 /* Allow continuing with the same signal that interrupted us.
1286 Otherwise complain. */
1288 child_continue (continue_status, pid);
1292 child_prepare_to_store ()
1294 /* Do nothing, since we can store individual regs */
1306 DEBUG_EVENTS (("gdb: child_close, inferior_pid=%d\n", inferior_pid));
1309 struct target_ops child_ops;
1312 init_child_ops (void)
1314 child_ops.to_shortname = "child";
1315 child_ops.to_longname = "Win32 child process";
1316 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1317 child_ops.to_open = child_open;
1318 child_ops.to_close = child_close;
1319 child_ops.to_attach = child_attach;
1320 child_ops.to_detach = child_detach;
1321 child_ops.to_resume = child_resume;
1322 child_ops.to_wait = child_wait;
1323 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1324 child_ops.to_store_registers = child_store_inferior_registers;
1325 child_ops.to_prepare_to_store = child_prepare_to_store;
1326 child_ops.to_xfer_memory = child_xfer_memory;
1327 child_ops.to_files_info = child_files_info;
1328 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1329 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1330 child_ops.to_terminal_init = terminal_init_inferior;
1331 child_ops.to_terminal_inferior = terminal_inferior;
1332 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1333 child_ops.to_terminal_ours = terminal_ours;
1334 child_ops.to_terminal_info = child_terminal_info;
1335 child_ops.to_kill = child_kill_inferior;
1336 child_ops.to_load = 0;
1337 child_ops.to_lookup_symbol = 0;
1338 child_ops.to_create_inferior = child_create_inferior;
1339 child_ops.to_mourn_inferior = child_mourn_inferior;
1340 child_ops.to_can_run = child_can_run;
1341 child_ops.to_notice_signals = 0;
1342 child_ops.to_thread_alive = win32_child_thread_alive;
1343 child_ops.to_pid_to_str = cygwin_pid_to_str;
1344 child_ops.to_stop = child_stop;
1345 child_ops.to_stratum = process_stratum;
1346 child_ops.DONT_USE = 0;
1347 child_ops.to_has_all_memory = 1;
1348 child_ops.to_has_memory = 1;
1349 child_ops.to_has_stack = 1;
1350 child_ops.to_has_registers = 1;
1351 child_ops.to_has_execution = 1;
1352 child_ops.to_sections = 0;
1353 child_ops.to_sections_end = 0;
1354 child_ops.to_magic = OPS_MAGIC;
1358 _initialize_inftarg ()
1362 add_com ("dll-symbols", class_files, dll_symbol_command,
1363 "Load dll library symbols from FILE.");
1365 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1367 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
1368 (char *) &new_console,
1369 "Set creation of new console when creating child process.",
1373 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
1374 (char *) &new_group,
1375 "Set creation of new group when creating child process.",
1379 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
1380 (char *) &debug_exec,
1381 "Set whether to display execution in child process.",
1385 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
1386 (char *) &debug_events,
1387 "Set whether to display kernel events in child process.",
1391 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
1392 (char *) &debug_memory,
1393 "Set whether to display memory accesses in child process.",
1397 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
1398 (char *) &debug_exceptions,
1399 "Set whether to display kernel exceptions in child process.",
1403 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1404 add_info_alias ("sharedlibrary", "dll", 1);
1406 add_target (&child_ops);
1409 /* Determine if the thread referenced by "pid" is alive
1410 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1411 it means that the pid has died. Otherwise it is assumed to be alive. */
1413 win32_child_thread_alive (int pid)
1415 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1419 /* Convert pid to printable format. */
1421 cygwin_pid_to_str (int pid)
1423 static char buf[80];
1424 if ((DWORD) pid == current_event.dwProcessId)
1425 sprintf (buf, "process %d", pid);
1427 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);