1 /* Target-vector operations for controlling windows child processes, for GDB.
3 Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
6 Contributed by Cygnus Solutions, A Red Hat Company.
8 This file is part of GDB.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 /* Originally by Steve Chamberlain, sac@cygnus.com */
26 #include "frame.h" /* required by inferior.h */
29 #include "exceptions.h"
32 #include "completer.h"
36 #include <sys/types.h>
43 #include <sys/cygwin.h>
50 #include "gdb_obstack.h"
51 #include "gdb_string.h"
52 #include "gdbthread.h"
54 #include <sys/param.h>
59 #include "xml-support.h"
61 #include "i386-tdep.h"
62 #include "i387-tdep.h"
64 #include "windows-tdep.h"
65 #include "windows-nat.h"
67 #define DebugActiveProcessStop dyn_DebugActiveProcessStop
68 #define DebugBreakProcess dyn_DebugBreakProcess
69 #define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit
70 #define EnumProcessModules dyn_EnumProcessModules
71 #define GetModuleFileNameExA dyn_GetModuleFileNameExA
72 #define GetModuleInformation dyn_GetModuleInformation
74 /* Since Windows XP, detaching from a process is supported by Windows.
75 The following code tries loading the appropriate functions dynamically.
76 If loading these functions succeeds use them to actually detach from
77 the inferior process, otherwise behave as usual, pretending that
79 static BOOL WINAPI (*DebugActiveProcessStop) (DWORD);
80 static BOOL WINAPI (*DebugBreakProcess) (HANDLE);
81 static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL);
82 static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD,
84 static DWORD WINAPI (*GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR,
86 static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO,
89 static struct target_ops windows_ops;
92 /* The starting and ending address of the cygwin1.dll text segment. */
93 static CORE_ADDR cygwin_load_start;
94 static CORE_ADDR cygwin_load_end;
97 static int have_saved_context; /* True if we've saved context from a cygwin signal. */
98 static CONTEXT saved_context; /* Containes the saved context from a cygwin signal. */
100 /* If we're not using the old Cygwin header file set, define the
101 following which never should have been in the generic Win32 API
102 headers in the first place since they were our own invention... */
103 #ifndef _GNU_H_WINDOWS_H
106 FLAG_TRACE_BIT = 0x100,
107 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
111 #ifndef CONTEXT_EXTENDED_REGISTERS
112 /* This macro is only defined on ia32. It only makes sense on this target,
113 so define it as zero if not already defined. */
114 #define CONTEXT_EXTENDED_REGISTERS 0
117 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
118 | CONTEXT_EXTENDED_REGISTERS
120 static uintptr_t dr[8];
121 static int debug_registers_changed;
122 static int debug_registers_used;
123 #define DR6_CLEAR_VALUE 0xffff0ff0
125 /* The string sent by cygwin when it processes a signal.
126 FIXME: This should be in a cygwin include file. */
127 #ifndef _CYGWIN_SIGNAL_STRING
128 #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
131 #define CHECK(x) check (x, __FILE__,__LINE__)
132 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
133 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
134 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
135 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
137 static void windows_stop (ptid_t);
138 static int windows_thread_alive (struct target_ops *, ptid_t);
139 static void windows_kill_inferior (struct target_ops *);
141 static enum target_signal last_sig = TARGET_SIGNAL_0;
142 /* Set if a signal was received from the debugged process */
144 /* Thread information structure used to track information that is
145 not available in gdb's thread structure. */
146 typedef struct thread_info_struct
148 struct thread_info_struct *next;
159 static thread_info thread_head;
161 /* The process and thread handles for the above context. */
163 static DEBUG_EVENT current_event; /* The current debug event from
165 static HANDLE current_process_handle; /* Currently executing process */
166 static thread_info *current_thread; /* Info on currently selected thread */
167 static DWORD main_thread_id; /* Thread ID of the main thread */
169 /* Counts of things. */
170 static int exception_count = 0;
171 static int event_count = 0;
172 static int saw_create;
173 static int open_process_used = 0;
176 static int new_console = 0;
178 static int cygwin_exceptions = 0;
180 static int new_group = 1;
181 static int debug_exec = 0; /* show execution */
182 static int debug_events = 0; /* show events from kernel */
183 static int debug_memory = 0; /* show target memory accesses */
184 static int debug_exceptions = 0; /* show target exceptions */
185 static int useshell = 0; /* use shell for subprocesses */
187 /* This vector maps GDB's idea of a register's number into an offset
188 in the windows exception context vector.
190 It also contains the bit mask needed to load the register in question.
192 The contents of this table can only be computed by the units
193 that provide CPU-specific support for Windows native debugging.
194 These units should set the table by calling
195 windows_set_context_register_offsets.
197 One day we could read a reg, we could inspect the context we
198 already have loaded, if it doesn't have the bit set that we need,
199 we read that set of registers in using GetThreadContext. If the
200 context already contains what we need, we just unpack it. Then to
201 write a register, first we have to ensure that the context contains
202 the other regs of the group, and then we copy the info in and set
205 static const int *mappings;
207 /* This vector maps the target's idea of an exception (extracted
208 from the DEBUG_EVENT structure) to GDB's idea. */
210 struct xlate_exception
213 enum target_signal us;
216 static const struct xlate_exception
219 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
220 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
221 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
222 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
223 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
224 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
227 /* Set the MAPPINGS static global to OFFSETS.
228 See the description of MAPPINGS for more details. */
231 windows_set_context_register_offsets (const int *offsets)
237 check (BOOL ok, const char *file, int line)
240 printf_filtered ("error return %s:%d was %lu\n", file, line,
244 /* Find a thread record given a thread id. If GET_CONTEXT is not 0,
245 then also retrieve the context for this thread. If GET_CONTEXT is
246 negative, then don't suspend the thread. */
248 thread_rec (DWORD id, int get_context)
252 for (th = &thread_head; (th = th->next) != NULL;)
255 if (!th->suspended && get_context)
257 if (get_context > 0 && id != current_event.dwThreadId)
259 if (SuspendThread (th->h) == (DWORD) -1)
261 DWORD err = GetLastError ();
262 warning (_("SuspendThread failed. (winerr %d)"),
268 else if (get_context < 0)
270 th->reload_context = 1;
278 /* Add a thread to the thread list. */
280 windows_add_thread (ptid_t ptid, HANDLE h)
285 gdb_assert (ptid_get_tid (ptid) != 0);
287 id = ptid_get_tid (ptid);
289 if ((th = thread_rec (id, FALSE)))
292 th = XZALLOC (thread_info);
295 th->next = thread_head.next;
296 thread_head.next = th;
298 /* Set the debug registers for the new thread if they are used. */
299 if (debug_registers_used)
301 /* Only change the value of the debug registers. */
302 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
303 CHECK (GetThreadContext (th->h, &th->context));
304 th->context.Dr0 = dr[0];
305 th->context.Dr1 = dr[1];
306 th->context.Dr2 = dr[2];
307 th->context.Dr3 = dr[3];
308 th->context.Dr6 = DR6_CLEAR_VALUE;
309 th->context.Dr7 = dr[7];
310 CHECK (SetThreadContext (th->h, &th->context));
311 th->context.ContextFlags = 0;
316 /* Clear out any old thread list and reintialize it to a
319 windows_init_thread_list (void)
321 thread_info *th = &thread_head;
323 DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
325 while (th->next != NULL)
327 thread_info *here = th->next;
328 th->next = here->next;
331 thread_head.next = NULL;
334 /* Delete a thread from the list of threads */
336 windows_delete_thread (ptid_t ptid)
341 gdb_assert (ptid_get_tid (ptid) != 0);
343 id = ptid_get_tid (ptid);
346 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid));
347 delete_thread (ptid);
349 for (th = &thread_head;
350 th->next != NULL && th->next->id != id;
354 if (th->next != NULL)
356 thread_info *here = th->next;
357 th->next = here->next;
363 do_windows_fetch_inferior_registers (struct regcache *regcache, int r)
365 char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
366 struct gdbarch *gdbarch = get_regcache_arch (regcache);
367 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
371 return; /* Windows sometimes uses a non-existent thread id in its
374 if (current_thread->reload_context)
376 #ifdef __COPY_CONTEXT_SIZE
377 if (have_saved_context)
379 /* Lie about where the program actually is stopped since cygwin has informed us that
380 we should consider the signal to have occurred at another location which is stored
381 in "saved_context. */
382 memcpy (¤t_thread->context, &saved_context, __COPY_CONTEXT_SIZE);
383 have_saved_context = 0;
388 thread_info *th = current_thread;
389 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
390 GetThreadContext (th->h, &th->context);
391 /* Copy dr values from that thread.
392 But only if there were not modified since last stop. PR gdb/2388 */
393 if (!debug_registers_changed)
395 dr[0] = th->context.Dr0;
396 dr[1] = th->context.Dr1;
397 dr[2] = th->context.Dr2;
398 dr[3] = th->context.Dr3;
399 dr[6] = th->context.Dr6;
400 dr[7] = th->context.Dr7;
403 current_thread->reload_context = 0;
406 if (r == I387_FISEG_REGNUM (tdep))
408 l = *((long *) context_offset) & 0xffff;
409 regcache_raw_supply (regcache, r, (char *) &l);
411 else if (r == I387_FOP_REGNUM (tdep))
413 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
414 regcache_raw_supply (regcache, r, (char *) &l);
417 regcache_raw_supply (regcache, r, context_offset);
420 for (r = 0; r < gdbarch_num_regs (gdbarch); r++)
421 do_windows_fetch_inferior_registers (regcache, r);
426 windows_fetch_inferior_registers (struct target_ops *ops,
427 struct regcache *regcache, int r)
429 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
430 /* Check if current_thread exists. Windows sometimes uses a non-existent
431 thread id in its events */
433 do_windows_fetch_inferior_registers (regcache, r);
437 do_windows_store_inferior_registers (const struct regcache *regcache, int r)
440 /* Windows sometimes uses a non-existent thread id in its events */;
442 regcache_raw_collect (regcache, r,
443 ((char *) ¤t_thread->context) + mappings[r]);
446 for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++)
447 do_windows_store_inferior_registers (regcache, r);
451 /* Store a new register value into the current thread context */
453 windows_store_inferior_registers (struct target_ops *ops,
454 struct regcache *regcache, int r)
456 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE);
457 /* Check if current_thread exists. Windows sometimes uses a non-existent
458 thread id in its events */
460 do_windows_store_inferior_registers (regcache, r);
463 /* Get the name of a given module at at given base address. If base_address
464 is zero return the first loaded module (which is always the name of the
467 get_module_name (LPVOID base_address, char *dll_name_ret)
473 HMODULE *DllHandle = dh_buf; /* Set to temporary storage for initial query */
476 char pathbuf[PATH_MAX + 1]; /* Temporary storage prior to converting to
479 char *pathbuf = dll_name_ret; /* Just copy directly to passed-in arg */
483 /* Find size of buffer needed to handle list of modules loaded in inferior */
484 if (!EnumProcessModules (current_process_handle, DllHandle,
485 sizeof (HMODULE), &cbNeeded) || !cbNeeded)
488 /* Allocate correct amount of space for module list */
489 DllHandle = (HMODULE *) alloca (cbNeeded);
493 /* Get the list of modules */
494 if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded,
498 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
500 /* Get information on this module */
501 if (!GetModuleInformation (current_process_handle, DllHandle[i],
503 error (_("Can't get module info"));
505 if (!base_address || mi.lpBaseOfDll == base_address)
507 /* Try to find the name of the given module */
508 len = GetModuleFileNameExA (current_process_handle,
509 DllHandle[i], pathbuf, MAX_PATH);
511 error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
513 /* Cygwin prefers that the path be in /x/y/z format */
514 cygwin_conv_to_full_posix_path (pathbuf, dll_name_ret);
516 return 1; /* success */
521 dll_name_ret[0] = '\0';
522 return 0; /* failure */
525 /* Encapsulate the information required in a call to
526 symbol_file_add_args */
527 struct safe_symbol_file_add_args
531 struct section_addr_info *addrs;
534 struct ui_file *err, *out;
538 /* Maintain a linked list of "so" information. */
544 static struct so_list solib_start, *solib_end;
546 /* Call symbol_file_add with stderr redirected. We don't care if there
549 safe_symbol_file_add_stub (void *argv)
551 #define p ((struct safe_symbol_file_add_args *) argv)
552 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
557 /* Restore gdb's stderr after calling symbol_file_add */
559 safe_symbol_file_add_cleanup (void *p)
561 #define sp ((struct safe_symbol_file_add_args *)p)
562 gdb_flush (gdb_stderr);
563 gdb_flush (gdb_stdout);
564 ui_file_delete (gdb_stderr);
565 ui_file_delete (gdb_stdout);
566 gdb_stderr = sp->err;
567 gdb_stdout = sp->out;
571 /* symbol_file_add wrapper that prevents errors from being displayed. */
572 static struct objfile *
573 safe_symbol_file_add (char *name, int from_tty,
574 struct section_addr_info *addrs,
575 int mainline, int flags)
577 struct safe_symbol_file_add_args p;
578 struct cleanup *cleanup;
580 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
584 gdb_flush (gdb_stderr);
585 gdb_flush (gdb_stdout);
586 gdb_stderr = ui_file_new ();
587 gdb_stdout = ui_file_new ();
589 p.from_tty = from_tty;
591 p.mainline = mainline;
593 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
595 do_cleanups (cleanup);
599 static struct so_list *
600 windows_make_so (const char *name, LPVOID load_addr)
603 char buf[MAX_PATH + 1];
604 char cwd[MAX_PATH + 1];
606 WIN32_FIND_DATA w32_fd;
607 HANDLE h = FindFirstFile(name, &w32_fd);
608 MEMORY_BASIC_INFORMATION m;
610 if (h == INVALID_HANDLE_VALUE)
616 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
618 p = strrchr (buf, '\\');
621 SetCurrentDirectory (buf);
622 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
623 SetCurrentDirectory (cwd);
627 if (strcasecmp (buf, "ntdll.dll") == 0)
629 GetSystemDirectory (buf, sizeof (buf));
630 strcat (buf, "\\ntdll.dll");
632 so = XZALLOC (struct so_list);
633 so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info));
634 so->lm_info->load_addr = load_addr;
635 strcpy (so->so_original_name, name);
637 strcpy (so->so_name, buf);
639 cygwin_conv_to_posix_path (buf, so->so_name);
640 /* Record cygwin1.dll .text start/end. */
641 p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
642 if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
645 asection *text = NULL;
648 abfd = bfd_openr (so->so_name, "pei-i386");
653 if (bfd_check_format (abfd, bfd_object))
654 text = bfd_get_section_by_name (abfd, ".text");
662 /* The symbols in a dll are offset by 0x1000, which is the the
663 offset from 0 of the first byte in an image - because of the
664 file header and the section alignment. */
665 cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) load_addr + 0x1000);
666 cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text);
676 get_image_name (HANDLE h, void *address, int unicode)
678 static char buf[(2 * MAX_PATH) + 1];
679 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
685 /* Attempt to read the name of the dll that was detected.
686 This is documented to work only when actively debugging
687 a program. It will not work for attached processes. */
691 /* See if we could read the address of a string, and that the
692 address isn't null. */
693 if (!ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done)
694 || done != sizeof (address_ptr) || !address_ptr)
697 /* Find the length of the string */
698 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
699 && (b[0] != 0 || b[size - 1] != 0) && done == size)
703 ReadProcessMemory (h, address_ptr, buf, len, &done);
706 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
707 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
710 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, len, 0, 0);
716 /* Wait for child to do something. Return pid of child, or -1 in case
717 of error; store status through argument pointer OURSTATUS. */
719 handle_load_dll (void *dummy)
721 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
722 char dll_buf[MAX_PATH + 1];
723 char *dll_name = NULL;
725 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
727 if (!get_module_name (event->lpBaseOfDll, dll_buf))
728 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
732 if (*dll_name == '\0')
733 dll_name = get_image_name (current_process_handle,
734 event->lpImageName, event->fUnicode);
738 solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
739 solib_end = solib_end->next;
741 DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %p.\n", solib_end->so_name,
742 solib_end->lm_info->load_addr));
748 windows_free_so (struct so_list *so)
756 handle_unload_dll (void *dummy)
758 LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
761 for (so = &solib_start; so->next != NULL; so = so->next)
762 if (so->next->lm_info->load_addr == lpBaseOfDll)
764 struct so_list *sodel = so->next;
765 so->next = sodel->next;
768 DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
770 windows_free_so (sodel);
771 solib_add (NULL, 0, NULL, auto_solib_add);
775 error (_("Error: dll starting at %p not found."), lpBaseOfDll);
780 /* Clear list of loaded DLLs. */
782 windows_clear_solib (void)
784 solib_start.next = NULL;
785 solib_end = &solib_start;
788 /* Load DLL symbol info. */
790 dll_symbol_command (char *args, int from_tty)
796 error (_("dll-symbols requires a file name"));
799 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
801 char *newargs = (char *) alloca (n + 4 + 1);
802 strcpy (newargs, args);
803 strcat (newargs, ".dll");
807 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
810 /* Handle DEBUG_STRING output from child process.
811 Cygwin prepends its messages with a "cygwin:". Interpret this as
812 a Cygwin signal. Otherwise just print the string as a warning. */
814 handle_output_debug_string (struct target_waitstatus *ourstatus)
819 if (!target_read_string
820 ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
824 else if (strncmp (s, _CYGWIN_SIGNAL_STRING, sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
827 if (strncmp (s, "cYg", 3) != 0)
831 #ifdef __COPY_CONTEXT_SIZE
834 /* Got a cygwin signal marker. A cygwin signal is followed by the signal number
835 itself and then optionally followed by the thread id and address to saved context
836 within the DLL. If these are supplied, then the given thread is assumed to have
837 issued the signal and the context from the thread is assumed to be stored at the
838 given address in the inferior. Tell gdb to treat this like a real signal. */
840 int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
841 int gotasig = target_signal_from_host (sig);
842 ourstatus->value.sig = gotasig;
847 ourstatus->kind = TARGET_WAITKIND_STOPPED;
848 retval = strtoul (p, &p, 0);
850 retval = main_thread_id;
851 else if ((x = (LPCVOID) strtoul (p, &p, 0))
852 && ReadProcessMemory (current_process_handle, x,
853 &saved_context, __COPY_CONTEXT_SIZE, &n)
854 && n == __COPY_CONTEXT_SIZE)
855 have_saved_context = 1;
856 current_event.dwThreadId = retval;
867 display_selector (HANDLE thread, DWORD sel)
870 if (GetThreadSelectorEntry (thread, sel, &info))
873 printf_filtered ("0x%03lx: ", sel);
874 if (!info.HighWord.Bits.Pres)
876 puts_filtered ("Segment not present\n");
879 base = (info.HighWord.Bits.BaseHi << 24) +
880 (info.HighWord.Bits.BaseMid << 16)
882 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
883 if (info.HighWord.Bits.Granularity)
884 limit = (limit << 12) | 0xfff;
885 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
886 if (info.HighWord.Bits.Default_Big)
887 puts_filtered(" 32-bit ");
889 puts_filtered(" 16-bit ");
890 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
893 puts_filtered ("Data (Read-Only, Exp-up");
896 puts_filtered ("Data (Read/Write, Exp-up");
899 puts_filtered ("Unused segment (");
902 puts_filtered ("Data (Read/Write, Exp-down");
905 puts_filtered ("Code (Exec-Only, N.Conf");
908 puts_filtered ("Code (Exec/Read, N.Conf");
911 puts_filtered ("Code (Exec-Only, Conf");
914 puts_filtered ("Code (Exec/Read, Conf");
917 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
919 if ((info.HighWord.Bits.Type & 0x1) == 0)
920 puts_filtered(", N.Acc");
921 puts_filtered (")\n");
922 if ((info.HighWord.Bits.Type & 0x10) == 0)
923 puts_filtered("System selector ");
924 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
925 if (info.HighWord.Bits.Granularity)
926 puts_filtered ("Page granular.\n");
928 puts_filtered ("Byte granular.\n");
933 printf_filtered ("Invalid selector 0x%lx.\n",sel);
939 display_selectors (char * args, int from_tty)
943 puts_filtered ("Impossible to display selectors now.\n");
949 puts_filtered ("Selector $cs\n");
950 display_selector (current_thread->h,
951 current_thread->context.SegCs);
952 puts_filtered ("Selector $ds\n");
953 display_selector (current_thread->h,
954 current_thread->context.SegDs);
955 puts_filtered ("Selector $es\n");
956 display_selector (current_thread->h,
957 current_thread->context.SegEs);
958 puts_filtered ("Selector $ss\n");
959 display_selector (current_thread->h,
960 current_thread->context.SegSs);
961 puts_filtered ("Selector $fs\n");
962 display_selector (current_thread->h,
963 current_thread->context.SegFs);
964 puts_filtered ("Selector $gs\n");
965 display_selector (current_thread->h,
966 current_thread->context.SegGs);
971 sel = parse_and_eval_long (args);
972 printf_filtered ("Selector \"%s\"\n",args);
973 display_selector (current_thread->h, sel);
977 static struct cmd_list_element *info_w32_cmdlist = NULL;
980 info_w32_command (char *args, int from_tty)
982 help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
986 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
987 printf_unfiltered ("gdb: Target exception %s at %p\n", x, \
988 current_event.u.Exception.ExceptionRecord.ExceptionAddress)
991 handle_exception (struct target_waitstatus *ourstatus)
994 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
996 ourstatus->kind = TARGET_WAITKIND_STOPPED;
998 /* Record the context of the current thread */
999 th = thread_rec (current_event.dwThreadId, -1);
1003 case EXCEPTION_ACCESS_VIOLATION:
1004 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1005 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1008 /* See if the access violation happened within the cygwin DLL itself. Cygwin uses
1009 a kind of exception handling to deal with passed-in invalid addresses. gdb
1010 should not treat these as real SEGVs since they will be silently handled by
1011 cygwin. A real SEGV will (theoretically) be caught by cygwin later in the process
1012 and will be sent as a cygwin-specific-signal. So, ignore SEGVs if they show up
1013 within the text segment of the DLL itself. */
1015 CORE_ADDR addr = (CORE_ADDR) (uintptr_t) current_event.u.Exception.ExceptionRecord.ExceptionAddress;
1016 if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end))
1017 || (find_pc_partial_function (addr, &fn, NULL, NULL)
1018 && strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0))
1023 case STATUS_STACK_OVERFLOW:
1024 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1025 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
1027 case STATUS_FLOAT_DENORMAL_OPERAND:
1028 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1029 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1031 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1032 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1033 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1035 case STATUS_FLOAT_INEXACT_RESULT:
1036 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1037 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1039 case STATUS_FLOAT_INVALID_OPERATION:
1040 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1041 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1043 case STATUS_FLOAT_OVERFLOW:
1044 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1045 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1047 case STATUS_FLOAT_STACK_CHECK:
1048 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1049 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1051 case STATUS_FLOAT_UNDERFLOW:
1052 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1053 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1055 case STATUS_FLOAT_DIVIDE_BY_ZERO:
1056 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1057 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1059 case STATUS_INTEGER_DIVIDE_BY_ZERO:
1060 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
1061 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1063 case STATUS_INTEGER_OVERFLOW:
1064 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1065 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1067 case EXCEPTION_BREAKPOINT:
1068 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1069 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1072 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1073 ourstatus->value.sig = TARGET_SIGNAL_INT;
1075 case DBG_CONTROL_BREAK:
1076 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
1077 ourstatus->value.sig = TARGET_SIGNAL_INT;
1079 case EXCEPTION_SINGLE_STEP:
1080 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1081 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1083 case EXCEPTION_ILLEGAL_INSTRUCTION:
1084 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1085 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1087 case EXCEPTION_PRIV_INSTRUCTION:
1088 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1089 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1091 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1092 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
1093 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1096 /* Treat unhandled first chance exceptions specially. */
1097 if (current_event.u.Exception.dwFirstChance)
1099 printf_unfiltered ("gdb: unknown target exception 0x%08lx at %p\n",
1100 current_event.u.Exception.ExceptionRecord.ExceptionCode,
1101 current_event.u.Exception.ExceptionRecord.ExceptionAddress);
1102 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1106 last_sig = ourstatus->value.sig;
1110 /* Resume all artificially suspended threads if we are continuing
1113 windows_continue (DWORD continue_status, int id)
1119 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1120 current_event.dwProcessId, current_event.dwThreadId,
1121 continue_status == DBG_CONTINUE ?
1122 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
1124 for (th = &thread_head; (th = th->next) != NULL;)
1125 if ((id == -1 || id == (int) th->id)
1128 if (debug_registers_changed)
1130 th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
1131 th->context.Dr0 = dr[0];
1132 th->context.Dr1 = dr[1];
1133 th->context.Dr2 = dr[2];
1134 th->context.Dr3 = dr[3];
1135 th->context.Dr6 = DR6_CLEAR_VALUE;
1136 th->context.Dr7 = dr[7];
1138 if (th->context.ContextFlags)
1140 CHECK (SetThreadContext (th->h, &th->context));
1141 th->context.ContextFlags = 0;
1143 if (th->suspended > 0)
1144 (void) ResumeThread (th->h);
1148 res = ContinueDebugEvent (current_event.dwProcessId,
1149 current_event.dwThreadId,
1152 debug_registers_changed = 0;
1156 /* Called in pathological case where Windows fails to send a
1157 CREATE_PROCESS_DEBUG_EVENT after an attach. */
1159 fake_create_process (void)
1161 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1162 current_event.dwProcessId);
1163 if (current_process_handle != NULL)
1164 open_process_used = 1;
1167 error (_("OpenProcess call failed, GetLastError = %lud\n"),
1169 /* We can not debug anything in that case. */
1171 main_thread_id = current_event.dwThreadId;
1172 current_thread = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1173 current_event.dwThreadId),
1174 current_event.u.CreateThread.hThread);
1175 return main_thread_id;
1179 windows_resume (struct target_ops *ops,
1180 ptid_t ptid, int step, enum target_signal sig)
1183 DWORD continue_status = DBG_CONTINUE;
1185 /* A specific PTID means `step only this thread id'. */
1186 int resume_all = ptid_equal (ptid, minus_one_ptid);
1188 /* If we're continuing all threads, it's the current inferior that
1189 should be handled specially. */
1191 ptid = inferior_ptid;
1193 if (sig != TARGET_SIGNAL_0)
1195 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1197 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1199 else if (sig == last_sig)
1200 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1203 /* This code does not seem to work, because
1204 the kernel does probably not consider changes in the ExceptionRecord
1205 structure when passing the exception to the inferior.
1206 Note that this seems possible in the exception handler itself. */
1209 for (i = 0; xlate[i].them != -1; i++)
1210 if (xlate[i].us == sig)
1212 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1214 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1217 if (continue_status == DBG_CONTINUE)
1219 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1223 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
1227 last_sig = TARGET_SIGNAL_0;
1229 DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n",
1230 ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig));
1232 /* Get context for currently selected thread */
1233 th = thread_rec (ptid_get_tid (inferior_ptid), FALSE);
1238 /* Single step by setting t bit */
1239 windows_fetch_inferior_registers (ops,
1240 get_current_regcache (),
1241 gdbarch_ps_regnum (current_gdbarch));
1242 th->context.EFlags |= FLAG_TRACE_BIT;
1245 if (th->context.ContextFlags)
1247 if (debug_registers_changed)
1249 th->context.Dr0 = dr[0];
1250 th->context.Dr1 = dr[1];
1251 th->context.Dr2 = dr[2];
1252 th->context.Dr3 = dr[3];
1253 th->context.Dr6 = DR6_CLEAR_VALUE;
1254 th->context.Dr7 = dr[7];
1256 CHECK (SetThreadContext (th->h, &th->context));
1257 th->context.ContextFlags = 0;
1261 /* Allow continuing with the same signal that interrupted us.
1262 Otherwise complain. */
1265 windows_continue (continue_status, -1);
1267 windows_continue (continue_status, ptid_get_tid (ptid));
1270 /* Get the next event from the child. Return 1 if the event requires
1271 handling by WFI (or whatever).
1274 get_windows_debug_event (struct target_ops *ops,
1275 int pid, struct target_waitstatus *ourstatus)
1278 DWORD continue_status, event_code;
1280 static thread_info dummy_thread_info;
1283 last_sig = TARGET_SIGNAL_0;
1285 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000)))
1289 continue_status = DBG_CONTINUE;
1291 event_code = current_event.dwDebugEventCode;
1292 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
1294 have_saved_context = 0;
1298 case CREATE_THREAD_DEBUG_EVENT:
1299 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
1300 (unsigned) current_event.dwProcessId,
1301 (unsigned) current_event.dwThreadId,
1302 "CREATE_THREAD_DEBUG_EVENT"));
1303 if (saw_create != 1)
1305 struct inferior *inf;
1306 inf = find_inferior_pid (current_event.dwProcessId);
1307 if (!saw_create && inf->attach_flag)
1309 /* Kludge around a Windows bug where first event is a create
1310 thread event. Caused when attached process does not have
1312 retval = fake_create_process ();
1318 /* Record the existence of this thread */
1319 retval = current_event.dwThreadId;
1320 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1321 current_event.dwThreadId),
1322 current_event.u.CreateThread.hThread);
1325 case EXIT_THREAD_DEBUG_EVENT:
1326 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1327 (unsigned) current_event.dwProcessId,
1328 (unsigned) current_event.dwThreadId,
1329 "EXIT_THREAD_DEBUG_EVENT"));
1330 if (current_event.dwThreadId != main_thread_id)
1332 windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1333 current_event.dwThreadId));
1334 th = &dummy_thread_info;
1338 case CREATE_PROCESS_DEBUG_EVENT:
1339 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1340 (unsigned) current_event.dwProcessId,
1341 (unsigned) current_event.dwThreadId,
1342 "CREATE_PROCESS_DEBUG_EVENT"));
1343 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1344 if (++saw_create != 1)
1347 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
1349 windows_delete_thread (ptid_build (current_event.dwProcessId, 0,
1351 main_thread_id = current_event.dwThreadId;
1352 /* Add the main thread */
1353 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0,
1354 current_event.dwThreadId),
1355 current_event.u.CreateProcessInfo.hThread);
1356 retval = current_event.dwThreadId;
1359 case EXIT_PROCESS_DEBUG_EVENT:
1360 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1361 (unsigned) current_event.dwProcessId,
1362 (unsigned) current_event.dwThreadId,
1363 "EXIT_PROCESS_DEBUG_EVENT"));
1364 if (saw_create != 1)
1366 ourstatus->kind = TARGET_WAITKIND_EXITED;
1367 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1368 retval = main_thread_id;
1371 case LOAD_DLL_DEBUG_EVENT:
1372 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1373 (unsigned) current_event.dwProcessId,
1374 (unsigned) current_event.dwThreadId,
1375 "LOAD_DLL_DEBUG_EVENT"));
1376 CloseHandle (current_event.u.LoadDll.hFile);
1377 if (saw_create != 1)
1379 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1380 ourstatus->kind = TARGET_WAITKIND_LOADED;
1381 ourstatus->value.integer = 0;
1382 retval = main_thread_id;
1385 case UNLOAD_DLL_DEBUG_EVENT:
1386 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1387 (unsigned) current_event.dwProcessId,
1388 (unsigned) current_event.dwThreadId,
1389 "UNLOAD_DLL_DEBUG_EVENT"));
1390 if (saw_create != 1)
1392 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1393 ourstatus->kind = TARGET_WAITKIND_LOADED;
1394 ourstatus->value.integer = 0;
1395 retval = main_thread_id;
1398 case EXCEPTION_DEBUG_EVENT:
1399 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1400 (unsigned) current_event.dwProcessId,
1401 (unsigned) current_event.dwThreadId,
1402 "EXCEPTION_DEBUG_EVENT"));
1403 if (saw_create != 1)
1405 switch (handle_exception (ourstatus))
1408 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1411 retval = current_event.dwThreadId;
1415 continue_status = -1;
1420 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1421 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
1422 (unsigned) current_event.dwProcessId,
1423 (unsigned) current_event.dwThreadId,
1424 "OUTPUT_DEBUG_STRING_EVENT"));
1425 if (saw_create != 1)
1427 retval = handle_output_debug_string (ourstatus);
1431 if (saw_create != 1)
1433 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1434 (DWORD) current_event.dwProcessId,
1435 (DWORD) current_event.dwThreadId);
1436 printf_unfiltered (" unknown event code %ld\n",
1437 current_event.dwDebugEventCode);
1441 if (!retval || saw_create != 1)
1443 if (continue_status == -1)
1444 windows_resume (ops, minus_one_ptid, 0, 1);
1446 CHECK (windows_continue (continue_status, -1));
1450 inferior_ptid = ptid_build (current_event.dwProcessId, 0,
1452 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
1459 /* Wait for interesting events to occur in the target process. */
1461 windows_wait (struct target_ops *ops,
1462 ptid_t ptid, struct target_waitstatus *ourstatus)
1466 target_terminal_ours ();
1468 /* We loop when we get a non-standard exception rather than return
1469 with a SPURIOUS because resume can try and step or modify things,
1470 which needs a current_thread->h. But some of these exceptions mark
1471 the birth or death of threads, which mean that the current thread
1472 isn't necessarily what you think it is. */
1478 /* Ignore CTRL+C signals while waiting for a debug event.
1479 FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
1480 the inferior is running, both the inferior and GDB receive the
1481 associated signal. If the inferior receives the signal first
1482 and the delay until GDB receives that signal is sufficiently long,
1483 GDB can sometimes receive the SIGINT after we have unblocked
1484 the CTRL+C handler. This would lead to the debugger to stop
1485 prematurely while handling the new-thread event that comes
1486 with the handling of the SIGINT inside the inferior, and then
1487 stop again immediately when the user tries to resume the execution
1488 in the inferior. This is a classic race, and it would be nice
1489 to find a better solution to that problem. But in the meantime,
1490 the current approach already greatly mitigate this issue. */
1491 SetConsoleCtrlHandler (NULL, TRUE);
1492 retval = get_windows_debug_event (ops, pid, ourstatus);
1493 SetConsoleCtrlHandler (NULL, FALSE);
1496 return ptid_build (current_event.dwProcessId, 0, retval);
1501 if (deprecated_ui_loop_hook != NULL)
1502 detach = deprecated_ui_loop_hook (0);
1505 windows_kill_inferior (ops);
1511 do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
1513 extern int stop_after_trap;
1515 struct inferior *inf;
1516 struct thread_info *tp;
1518 last_sig = TARGET_SIGNAL_0;
1520 exception_count = 0;
1521 open_process_used = 0;
1522 debug_registers_changed = 0;
1523 debug_registers_used = 0;
1524 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1527 cygwin_load_start = cygwin_load_end = 0;
1529 current_event.dwProcessId = pid;
1530 memset (¤t_event, 0, sizeof (current_event));
1532 disable_breakpoints_in_shlibs ();
1533 windows_clear_solib ();
1534 clear_proceed_status ();
1535 init_wait_for_inferior ();
1537 inf = add_inferior (pid);
1538 inf->attach_flag = attaching;
1540 /* Make the new process the current inferior, so terminal handling
1541 can rely on it. When attaching, we don't know about any thread
1542 id here, but that's OK --- nothing should be referencing the
1543 current thread until we report an event out of windows_wait. */
1544 inferior_ptid = pid_to_ptid (pid);
1546 terminal_init_inferior_with_pgrp (pid);
1547 target_terminal_inferior ();
1549 inf->stop_soon = STOP_QUIETLY;
1552 stop_after_trap = 1;
1553 wait_for_inferior (0);
1554 tp = inferior_thread ();
1555 if (tp->stop_signal != TARGET_SIGNAL_TRAP)
1556 resume (0, tp->stop_signal);
1561 inf->stop_soon = NO_STOP_QUIETLY;
1562 stop_after_trap = 0;
1566 /* Try to set or remove a user privilege to the current process. Return -1
1567 if that fails, the previous setting of that privilege otherwise.
1569 This code is copied from the Cygwin source code and rearranged to allow
1570 dynamically loading of the needed symbols from advapi32 which is only
1571 available on NT/2K/XP. */
1573 set_process_privilege (const char *privilege, BOOL enable)
1575 static HMODULE advapi32 = NULL;
1576 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1577 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1578 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1579 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1581 HANDLE token_hdl = NULL;
1583 TOKEN_PRIVILEGES new_priv, orig_priv;
1587 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1592 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1594 if (!OpenProcessToken)
1596 (void *) GetProcAddress (advapi32, "OpenProcessToken");
1597 if (!LookupPrivilegeValue)
1598 LookupPrivilegeValue =
1599 (void *) GetProcAddress (advapi32, "LookupPrivilegeValueA");
1600 if (!AdjustTokenPrivileges)
1601 AdjustTokenPrivileges =
1602 (void *) GetProcAddress (advapi32, "AdjustTokenPrivileges");
1603 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
1610 if (!OpenProcessToken (GetCurrentProcess (),
1611 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1615 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1618 new_priv.PrivilegeCount = 1;
1619 new_priv.Privileges[0].Luid = restore_priv;
1620 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1622 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
1623 sizeof orig_priv, &orig_priv, &size))
1626 /* Disabled, otherwise every `attach' in an unprivileged user session
1627 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1628 windows_attach(). */
1629 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1630 be enabled. GetLastError () returns an correct error code, though. */
1631 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1635 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1639 CloseHandle (token_hdl);
1644 /* Attach to process PID, then initialize for debugging it. */
1646 windows_attach (struct target_ops *ops, char *args, int from_tty)
1652 error_no_arg (_("process-id to attach"));
1654 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1656 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1657 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1660 pid = strtoul (args, 0, 0); /* Windows pid */
1662 windows_init_thread_list ();
1663 ok = DebugActiveProcess (pid);
1669 /* Try fall back to Cygwin pid */
1670 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1673 ok = DebugActiveProcess (pid);
1678 error (_("Can't attach to process."));
1680 DebugSetProcessKillOnExit (FALSE);
1684 char *exec_file = (char *) get_exec_file (0);
1687 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
1688 target_pid_to_str (pid_to_ptid (pid)));
1690 printf_unfiltered ("Attaching to %s\n",
1691 target_pid_to_str (pid_to_ptid (pid)));
1693 gdb_flush (gdb_stdout);
1696 do_initial_windows_stuff (ops, pid, 1);
1697 target_terminal_ours ();
1701 windows_detach (struct target_ops *ops, char *args, int from_tty)
1706 windows_resume (ops, ptid, 0, TARGET_SIGNAL_0);
1708 if (!DebugActiveProcessStop (current_event.dwProcessId))
1710 error (_("Can't detach process %lu (error %lu)"),
1711 current_event.dwProcessId, GetLastError ());
1714 DebugSetProcessKillOnExit (FALSE);
1716 if (detached && from_tty)
1718 char *exec_file = get_exec_file (0);
1721 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1722 current_event.dwProcessId);
1723 gdb_flush (gdb_stdout);
1726 inferior_ptid = null_ptid;
1727 detach_inferior (current_event.dwProcessId);
1729 unpush_target (ops);
1733 windows_pid_to_exec_file (int pid)
1735 static char path[MAX_PATH + 1];
1738 /* Try to find exe name as symlink target of /proc/<pid>/exe */
1740 char procexe[sizeof ("/proc/4294967295/exe")];
1741 sprintf (procexe, "/proc/%u/exe", pid);
1742 nchars = readlink (procexe, path, sizeof(path));
1743 if (nchars > 0 && nchars < sizeof (path))
1745 path[nchars] = '\0'; /* Got it */
1750 /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
1751 of gdb, or we're trying to debug a non-Cygwin windows executable. */
1752 if (!get_module_name (0, path))
1758 /* Print status information about what we're accessing. */
1761 windows_files_info (struct target_ops *ignore)
1763 struct inferior *inf = current_inferior ();
1765 printf_unfiltered ("\tUsing the running image of %s %s.\n",
1766 inf->attach_flag ? "attached" : "child",
1767 target_pid_to_str (inferior_ptid));
1771 windows_open (char *arg, int from_tty)
1773 error (_("Use the \"run\" command to start a Unix child process."));
1776 /* Start an inferior windows child process and sets inferior_ptid to its pid.
1777 EXEC_FILE is the file to run.
1778 ALLARGS is a string containing the arguments to the program.
1779 ENV is the environment vector to pass. Errors reported with error(). */
1782 windows_create_inferior (struct target_ops *ops, char *exec_file,
1783 char *allargs, char **in_env, int from_tty)
1786 PROCESS_INFORMATION pi;
1790 char real_path[MAXPATHLEN];
1792 char shell[MAX_PATH + 1]; /* Path to shell */
1796 int ostdin, ostdout, ostderr;
1800 const char *inferior_io_terminal = get_inferior_io_terminal ();
1803 error (_("No executable specified, use `target exec'."));
1805 memset (&si, 0, sizeof (si));
1806 si.cb = sizeof (si);
1811 flags = DEBUG_ONLY_THIS_PROCESS;
1812 cygwin_conv_to_win32_path (exec_file, real_path);
1818 sh = getenv ("SHELL");
1821 cygwin_conv_to_win32_path (sh, shell);
1822 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1823 + strlen (allargs) + 2);
1824 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1825 allargs = newallargs;
1827 flags = DEBUG_PROCESS;
1831 flags = DEBUG_ONLY_THIS_PROCESS;
1835 flags |= CREATE_NEW_PROCESS_GROUP;
1838 flags |= CREATE_NEW_CONSOLE;
1840 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1841 strcpy (args, toexec);
1843 strcat (args, allargs);
1846 /* Prepare the environment vars for CreateProcess. */
1847 cygwin_internal (CW_SYNC_WINENV);
1849 if (!inferior_io_terminal)
1850 tty = ostdin = ostdout = ostderr = -1;
1853 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1856 print_sys_errmsg (inferior_io_terminal, errno);
1857 ostdin = ostdout = ostderr = -1;
1870 if (!inferior_io_terminal)
1871 tty = INVALID_HANDLE_VALUE;
1874 SECURITY_ATTRIBUTES sa;
1875 sa.nLength = sizeof(sa);
1876 sa.lpSecurityDescriptor = 0;
1877 sa.bInheritHandle = TRUE;
1878 tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
1879 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
1880 if (tty == INVALID_HANDLE_VALUE)
1881 warning (_("Warning: Failed to open TTY %s, error %#x."),
1882 inferior_io_terminal, (unsigned) GetLastError ());
1886 si.hStdOutput = tty;
1888 si.dwFlags |= STARTF_USESTDHANDLES;
1893 windows_init_thread_list ();
1894 ret = CreateProcess (0,
1895 args, /* command line */
1896 NULL, /* Security */
1898 TRUE, /* inherit handles */
1899 flags, /* start flags */
1900 NULL, /* environment */
1901 NULL, /* current directory */
1917 if (tty != INVALID_HANDLE_VALUE)
1922 error (_("Error creating process %s, (error %d)."),
1923 exec_file, (unsigned) GetLastError ());
1925 CloseHandle (pi.hThread);
1926 CloseHandle (pi.hProcess);
1928 if (useshell && shell[0] != '\0')
1933 do_initial_windows_stuff (ops, pi.dwProcessId, 0);
1935 /* windows_continue (DBG_CONTINUE, -1); */
1939 windows_mourn_inferior (struct target_ops *ops)
1941 (void) windows_continue (DBG_CONTINUE, -1);
1942 i386_cleanup_dregs();
1943 if (open_process_used)
1945 CHECK (CloseHandle (current_process_handle));
1946 open_process_used = 0;
1948 unpush_target (ops);
1949 generic_mourn_inferior ();
1952 /* Send a SIGINT to the process group. This acts just like the user typed a
1953 ^C on the controlling terminal. */
1956 windows_stop (ptid_t ptid)
1958 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1959 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
1960 registers_changed (); /* refresh register state */
1964 windows_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len,
1965 int write, struct mem_attrib *mem,
1966 struct target_ops *target)
1971 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1972 len, (DWORD) (uintptr_t) memaddr));
1973 if (!WriteProcessMemory (current_process_handle,
1974 (LPVOID) (uintptr_t) memaddr, our,
1977 FlushInstructionCache (current_process_handle,
1978 (LPCVOID) (uintptr_t) memaddr, len);
1982 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1983 len, (DWORD) (uintptr_t) memaddr));
1984 if (!ReadProcessMemory (current_process_handle,
1985 (LPCVOID) (uintptr_t) memaddr, our,
1993 windows_kill_inferior (struct target_ops *ops)
1995 CHECK (TerminateProcess (current_process_handle, 0));
1999 if (!windows_continue (DBG_CONTINUE, -1))
2001 if (!WaitForDebugEvent (¤t_event, INFINITE))
2003 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
2007 target_mourn_inferior (); /* or just windows_mourn_inferior? */
2011 windows_prepare_to_store (struct regcache *regcache)
2013 /* Do nothing, since we can store individual regs */
2017 windows_can_run (void)
2023 windows_close (int x)
2025 DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
2026 PIDGET (inferior_ptid)));
2029 /* Convert pid to printable format. */
2031 windows_pid_to_str (struct target_ops *ops, ptid_t ptid)
2033 static char buf[80];
2035 if (ptid_get_tid (ptid) != 0)
2037 snprintf (buf, sizeof (buf), "Thread %d.0x%lx",
2038 ptid_get_pid (ptid), ptid_get_tid (ptid));
2042 return normal_pid_to_str (ptid);
2046 windows_xfer_shared_libraries (struct target_ops *ops,
2047 enum target_object object, const char *annex,
2048 gdb_byte *readbuf, const gdb_byte *writebuf,
2049 ULONGEST offset, LONGEST len)
2051 struct obstack obstack;
2059 obstack_init (&obstack);
2060 obstack_grow_str (&obstack, "<library-list>\n");
2061 for (so = solib_start.next; so; so = so->next)
2062 windows_xfer_shared_library (so->so_name, (CORE_ADDR) (uintptr_t) so->lm_info->load_addr,
2064 obstack_grow_str0 (&obstack, "</library-list>\n");
2066 buf = obstack_finish (&obstack);
2067 len_avail = strlen (buf);
2068 if (offset >= len_avail)
2071 if (len > len_avail - offset)
2072 len = len_avail - offset;
2073 memcpy (readbuf, buf + offset, len);
2075 obstack_free (&obstack, NULL);
2080 windows_xfer_partial (struct target_ops *ops, enum target_object object,
2081 const char *annex, gdb_byte *readbuf,
2082 const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
2086 case TARGET_OBJECT_MEMORY:
2088 return (*ops->deprecated_xfer_memory) (offset, readbuf,
2089 len, 0/*read*/, NULL, ops);
2091 return (*ops->deprecated_xfer_memory) (offset, (gdb_byte *) writebuf,
2092 len, 1/*write*/, NULL, ops);
2095 case TARGET_OBJECT_LIBRARIES:
2096 return windows_xfer_shared_libraries (ops, object, annex, readbuf,
2097 writebuf, offset, len);
2100 if (ops->beneath != NULL)
2101 return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
2102 readbuf, writebuf, offset, len);
2108 init_windows_ops (void)
2110 windows_ops.to_shortname = "child";
2111 windows_ops.to_longname = "Win32 child process";
2112 windows_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2113 windows_ops.to_open = windows_open;
2114 windows_ops.to_close = windows_close;
2115 windows_ops.to_attach = windows_attach;
2116 windows_ops.to_attach_no_wait = 1;
2117 windows_ops.to_detach = windows_detach;
2118 windows_ops.to_resume = windows_resume;
2119 windows_ops.to_wait = windows_wait;
2120 windows_ops.to_fetch_registers = windows_fetch_inferior_registers;
2121 windows_ops.to_store_registers = windows_store_inferior_registers;
2122 windows_ops.to_prepare_to_store = windows_prepare_to_store;
2123 windows_ops.deprecated_xfer_memory = windows_xfer_memory;
2124 windows_ops.to_xfer_partial = windows_xfer_partial;
2125 windows_ops.to_files_info = windows_files_info;
2126 windows_ops.to_insert_breakpoint = memory_insert_breakpoint;
2127 windows_ops.to_remove_breakpoint = memory_remove_breakpoint;
2128 windows_ops.to_terminal_init = terminal_init_inferior;
2129 windows_ops.to_terminal_inferior = terminal_inferior;
2130 windows_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2131 windows_ops.to_terminal_ours = terminal_ours;
2132 windows_ops.to_terminal_save_ours = terminal_save_ours;
2133 windows_ops.to_terminal_info = child_terminal_info;
2134 windows_ops.to_kill = windows_kill_inferior;
2135 windows_ops.to_create_inferior = windows_create_inferior;
2136 windows_ops.to_mourn_inferior = windows_mourn_inferior;
2137 windows_ops.to_can_run = windows_can_run;
2138 windows_ops.to_thread_alive = windows_thread_alive;
2139 windows_ops.to_pid_to_str = windows_pid_to_str;
2140 windows_ops.to_stop = windows_stop;
2141 windows_ops.to_stratum = process_stratum;
2142 windows_ops.to_has_all_memory = 1;
2143 windows_ops.to_has_memory = 1;
2144 windows_ops.to_has_stack = 1;
2145 windows_ops.to_has_registers = 1;
2146 windows_ops.to_has_execution = 1;
2147 windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file;
2148 i386_use_watchpoints (&windows_ops);
2150 windows_ops.to_magic = OPS_MAGIC;
2154 set_windows_aliases (char *argv0)
2156 add_info_alias ("dll", "sharedlibrary", 1);
2160 _initialize_windows_nat (void)
2162 struct cmd_list_element *c;
2164 init_windows_ops ();
2166 c = add_com ("dll-symbols", class_files, dll_symbol_command,
2167 _("Load dll library symbols from FILE."));
2168 set_cmd_completer (c, filename_completer);
2170 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2173 add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2174 Set use of shell to start subprocess."), _("\
2175 Show use of shell to start subprocess."), NULL,
2177 NULL, /* FIXME: i18n: */
2178 &setlist, &showlist);
2180 add_setshow_boolean_cmd ("cygwin-exceptions", class_support, &cygwin_exceptions, _("\
2181 Break when an exception is detected in the Cygwin DLL itself."), _("\
2182 Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
2184 NULL, /* FIXME: i18n: */
2185 &setlist, &showlist);
2188 add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2189 Set creation of new console when creating child process."), _("\
2190 Show creation of new console when creating child process."), NULL,
2192 NULL, /* FIXME: i18n: */
2193 &setlist, &showlist);
2195 add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2196 Set creation of new group when creating child process."), _("\
2197 Show creation of new group when creating child process."), NULL,
2199 NULL, /* FIXME: i18n: */
2200 &setlist, &showlist);
2202 add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2203 Set whether to display execution in child process."), _("\
2204 Show whether to display execution in child process."), NULL,
2206 NULL, /* FIXME: i18n: */
2207 &setlist, &showlist);
2209 add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2210 Set whether to display kernel events in child process."), _("\
2211 Show whether to display kernel events in child process."), NULL,
2213 NULL, /* FIXME: i18n: */
2214 &setlist, &showlist);
2216 add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2217 Set whether to display memory accesses in child process."), _("\
2218 Show whether to display memory accesses in child process."), NULL,
2220 NULL, /* FIXME: i18n: */
2221 &setlist, &showlist);
2223 add_setshow_boolean_cmd ("debugexceptions", class_support,
2224 &debug_exceptions, _("\
2225 Set whether to display kernel exceptions in child process."), _("\
2226 Show whether to display kernel exceptions in child process."), NULL,
2228 NULL, /* FIXME: i18n: */
2229 &setlist, &showlist);
2231 add_prefix_cmd ("w32", class_info, info_w32_command,
2232 _("Print information specific to Win32 debugging."),
2233 &info_w32_cmdlist, "info w32 ", 0, &infolist);
2235 add_cmd ("selector", class_info, display_selectors,
2236 _("Display selectors infos."),
2238 add_target (&windows_ops);
2239 deprecated_init_ui_hook = set_windows_aliases;
2242 /* Hardware watchpoint support, adapted from go32-nat.c code. */
2244 /* Pass the address ADDR to the inferior in the I'th debug register.
2245 Here we just store the address in dr array, the registers will be
2246 actually set up when windows_continue is called. */
2248 cygwin_set_dr (int i, CORE_ADDR addr)
2251 internal_error (__FILE__, __LINE__,
2252 _("Invalid register %d in cygwin_set_dr.\n"), i);
2254 debug_registers_changed = 1;
2255 debug_registers_used = 1;
2258 /* Pass the value VAL to the inferior in the DR7 debug control
2259 register. Here we just store the address in D_REGS, the watchpoint
2260 will be actually set up in windows_wait. */
2262 cygwin_set_dr7 (unsigned val)
2265 debug_registers_changed = 1;
2266 debug_registers_used = 1;
2269 /* Get the value of the DR6 debug status register from the inferior.
2270 Here we just return the value stored in dr[6]
2271 by the last call to thread_rec for current_event.dwThreadId id. */
2273 cygwin_get_dr6 (void)
2278 /* Determine if the thread referenced by "ptid" is alive
2279 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2280 it means that the thread has died. Otherwise it is assumed to be alive. */
2282 windows_thread_alive (struct target_ops *ops, ptid_t ptid)
2286 gdb_assert (ptid_get_tid (ptid) != 0);
2287 tid = ptid_get_tid (ptid);
2289 return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2294 _initialize_check_for_gdb_ini (void)
2297 if (inhibit_gdbinit)
2300 homedir = getenv ("HOME");
2304 char *oldini = (char *) alloca (strlen (homedir) +
2305 sizeof ("/gdb.ini"));
2306 strcpy (oldini, homedir);
2307 p = strchr (oldini, '\0');
2308 if (p > oldini && p[-1] != '/')
2310 strcpy (p, "gdb.ini");
2311 if (access (oldini, 0) == 0)
2313 int len = strlen (oldini);
2314 char *newini = alloca (len + 1);
2315 sprintf (newini, "%.*s.gdbinit",
2316 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2317 warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2322 /* Define dummy functions which always return error for the rare cases where
2323 these functions could not be found. */
2325 bad_DebugActiveProcessStop (DWORD w)
2330 bad_DebugBreakProcess (HANDLE w)
2335 bad_DebugSetProcessKillOnExit (BOOL w)
2340 bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
2345 bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
2350 bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
2355 /* Load any functions which may not be available in ancient versions
2358 _initialize_loadable (void)
2362 hm = LoadLibrary ("kernel32.dll");
2365 dyn_DebugActiveProcessStop = (void *)
2366 GetProcAddress (hm, "DebugActiveProcessStop");
2367 dyn_DebugBreakProcess = (void *)
2368 GetProcAddress (hm, "DebugBreakProcess");
2369 dyn_DebugSetProcessKillOnExit = (void *)
2370 GetProcAddress (hm, "DebugSetProcessKillOnExit");
2373 /* Set variables to dummy versions of these processes if the function
2374 wasn't found in kernel32.dll. */
2375 if (!dyn_DebugBreakProcess)
2376 dyn_DebugBreakProcess = bad_DebugBreakProcess;
2377 if (!dyn_DebugActiveProcessStop || !dyn_DebugSetProcessKillOnExit)
2379 dyn_DebugActiveProcessStop = bad_DebugActiveProcessStop;
2380 dyn_DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
2383 /* Load optional functions used for retrieving filename information
2384 associated with the currently debugged process or its dlls. */
2385 hm = LoadLibrary ("psapi.dll");
2388 dyn_EnumProcessModules = (void *)
2389 GetProcAddress (hm, "EnumProcessModules");
2390 dyn_GetModuleInformation = (void *)
2391 GetProcAddress (hm, "GetModuleInformation");
2392 dyn_GetModuleFileNameExA = (void *)
2393 GetProcAddress (hm, "GetModuleFileNameExA");
2396 if (!dyn_EnumProcessModules || !dyn_GetModuleInformation || !dyn_GetModuleFileNameExA)
2398 /* Set variables to dummy versions of these processes if the function
2399 wasn't found in psapi.dll. */
2400 dyn_EnumProcessModules = bad_EnumProcessModules;
2401 dyn_GetModuleInformation = bad_GetModuleInformation;
2402 dyn_GetModuleFileNameExA = bad_GetModuleFileNameExA;
2403 /* This will probably fail on Windows 9x/Me. Let the user know that we're
2404 missing some functionality. */
2405 warning(_("cannot automatically find executable file or library to read symbols. Use \"file\" or \"dll\" command to load executable/libraries directly."));