GDB (API)
|
00001 /* Target-vector operations for controlling windows child processes, for GDB. 00002 00003 Copyright (C) 1995-2013 Free Software Foundation, Inc. 00004 00005 Contributed by Cygnus Solutions, A Red Hat Company. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 /* Originally by Steve Chamberlain, sac@cygnus.com */ 00023 00024 #include "defs.h" 00025 #include "frame.h" /* required by inferior.h */ 00026 #include "inferior.h" 00027 #include "target.h" 00028 #include "exceptions.h" 00029 #include "gdbcore.h" 00030 #include "command.h" 00031 #include "completer.h" 00032 #include "regcache.h" 00033 #include "top.h" 00034 #include <signal.h> 00035 #include <sys/types.h> 00036 #include <fcntl.h> 00037 #include <stdlib.h> 00038 #include <windows.h> 00039 #include <imagehlp.h> 00040 #include <psapi.h> 00041 #ifdef __CYGWIN__ 00042 #include <wchar.h> 00043 #include <sys/cygwin.h> 00044 #include <cygwin/version.h> 00045 #endif 00046 #include <signal.h> 00047 00048 #include "buildsym.h" 00049 #include "filenames.h" 00050 #include "symfile.h" 00051 #include "objfiles.h" 00052 #include "gdb_bfd.h" 00053 #include "gdb_obstack.h" 00054 #include "gdb_string.h" 00055 #include "gdbthread.h" 00056 #include "gdbcmd.h" 00057 #include <unistd.h> 00058 #include "exec.h" 00059 #include "solist.h" 00060 #include "solib.h" 00061 #include "xml-support.h" 00062 00063 #include "i386-tdep.h" 00064 #include "i387-tdep.h" 00065 00066 #include "windows-tdep.h" 00067 #include "windows-nat.h" 00068 #include "i386-nat.h" 00069 #include "complaints.h" 00070 00071 #define AdjustTokenPrivileges dyn_AdjustTokenPrivileges 00072 #define DebugActiveProcessStop dyn_DebugActiveProcessStop 00073 #define DebugBreakProcess dyn_DebugBreakProcess 00074 #define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit 00075 #define EnumProcessModules dyn_EnumProcessModules 00076 #define GetModuleInformation dyn_GetModuleInformation 00077 #define LookupPrivilegeValueA dyn_LookupPrivilegeValueA 00078 #define OpenProcessToken dyn_OpenProcessToken 00079 #define GetConsoleFontSize dyn_GetConsoleFontSize 00080 #define GetCurrentConsoleFont dyn_GetCurrentConsoleFont 00081 00082 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, 00083 DWORD, PTOKEN_PRIVILEGES, PDWORD); 00084 static BOOL WINAPI (*DebugActiveProcessStop) (DWORD); 00085 static BOOL WINAPI (*DebugBreakProcess) (HANDLE); 00086 static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL); 00087 static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD, 00088 LPDWORD); 00089 static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, 00090 DWORD); 00091 static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID); 00092 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE); 00093 static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL, 00094 CONSOLE_FONT_INFO *); 00095 static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); 00096 00097 static struct target_ops windows_ops; 00098 00099 #undef STARTUPINFO 00100 #undef CreateProcess 00101 #undef GetModuleFileNameEx 00102 00103 #ifndef __CYGWIN__ 00104 # define __PMAX (MAX_PATH + 1) 00105 static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD); 00106 # define STARTUPINFO STARTUPINFOA 00107 # define CreateProcess CreateProcessA 00108 # define GetModuleFileNameEx_name "GetModuleFileNameExA" 00109 # define bad_GetModuleFileNameEx bad_GetModuleFileNameExA 00110 #else 00111 # define __PMAX PATH_MAX 00112 /* The starting and ending address of the cygwin1.dll text segment. */ 00113 static CORE_ADDR cygwin_load_start; 00114 static CORE_ADDR cygwin_load_end; 00115 # define __USEWIDE 00116 typedef wchar_t cygwin_buf_t; 00117 static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, 00118 LPWSTR, DWORD); 00119 # define STARTUPINFO STARTUPINFOW 00120 # define CreateProcess CreateProcessW 00121 # define GetModuleFileNameEx_name "GetModuleFileNameExW" 00122 # define bad_GetModuleFileNameEx bad_GetModuleFileNameExW 00123 #endif 00124 00125 static int have_saved_context; /* True if we've saved context from a 00126 cygwin signal. */ 00127 static CONTEXT saved_context; /* Containes the saved context from a 00128 cygwin signal. */ 00129 00130 /* If we're not using the old Cygwin header file set, define the 00131 following which never should have been in the generic Win32 API 00132 headers in the first place since they were our own invention... */ 00133 #ifndef _GNU_H_WINDOWS_H 00134 enum 00135 { 00136 FLAG_TRACE_BIT = 0x100, 00137 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT) 00138 }; 00139 #endif 00140 00141 #ifndef CONTEXT_EXTENDED_REGISTERS 00142 /* This macro is only defined on ia32. It only makes sense on this target, 00143 so define it as zero if not already defined. */ 00144 #define CONTEXT_EXTENDED_REGISTERS 0 00145 #endif 00146 00147 #define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \ 00148 | CONTEXT_EXTENDED_REGISTERS 00149 00150 static uintptr_t dr[8]; 00151 static int debug_registers_changed; 00152 static int debug_registers_used; 00153 00154 static int windows_initialization_done; 00155 #define DR6_CLEAR_VALUE 0xffff0ff0 00156 00157 /* The string sent by cygwin when it processes a signal. 00158 FIXME: This should be in a cygwin include file. */ 00159 #ifndef _CYGWIN_SIGNAL_STRING 00160 #define _CYGWIN_SIGNAL_STRING "cYgSiGw00f" 00161 #endif 00162 00163 #define CHECK(x) check (x, __FILE__,__LINE__) 00164 #define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x 00165 #define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x 00166 #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x 00167 #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x 00168 00169 static void windows_stop (ptid_t); 00170 static int windows_thread_alive (struct target_ops *, ptid_t); 00171 static void windows_kill_inferior (struct target_ops *); 00172 00173 static void cygwin_set_dr (int i, CORE_ADDR addr); 00174 static void cygwin_set_dr7 (unsigned long val); 00175 static CORE_ADDR cygwin_get_dr (int i); 00176 static unsigned long cygwin_get_dr6 (void); 00177 static unsigned long cygwin_get_dr7 (void); 00178 00179 static enum gdb_signal last_sig = GDB_SIGNAL_0; 00180 /* Set if a signal was received from the debugged process. */ 00181 00182 /* Thread information structure used to track information that is 00183 not available in gdb's thread structure. */ 00184 typedef struct thread_info_struct 00185 { 00186 struct thread_info_struct *next; 00187 DWORD id; 00188 HANDLE h; 00189 CORE_ADDR thread_local_base; 00190 char *name; 00191 int suspended; 00192 int reload_context; 00193 CONTEXT context; 00194 STACKFRAME sf; 00195 } 00196 thread_info; 00197 00198 static thread_info thread_head; 00199 00200 /* The process and thread handles for the above context. */ 00201 00202 static DEBUG_EVENT current_event; /* The current debug event from 00203 WaitForDebugEvent */ 00204 static HANDLE current_process_handle; /* Currently executing process */ 00205 static thread_info *current_thread; /* Info on currently selected thread */ 00206 static DWORD main_thread_id; /* Thread ID of the main thread */ 00207 00208 /* Counts of things. */ 00209 static int exception_count = 0; 00210 static int event_count = 0; 00211 static int saw_create; 00212 static int open_process_used = 0; 00213 00214 /* User options. */ 00215 static int new_console = 0; 00216 #ifdef __CYGWIN__ 00217 static int cygwin_exceptions = 0; 00218 #endif 00219 static int new_group = 1; 00220 static int debug_exec = 0; /* show execution */ 00221 static int debug_events = 0; /* show events from kernel */ 00222 static int debug_memory = 0; /* show target memory accesses */ 00223 static int debug_exceptions = 0; /* show target exceptions */ 00224 static int useshell = 0; /* use shell for subprocesses */ 00225 00226 /* This vector maps GDB's idea of a register's number into an offset 00227 in the windows exception context vector. 00228 00229 It also contains the bit mask needed to load the register in question. 00230 00231 The contents of this table can only be computed by the units 00232 that provide CPU-specific support for Windows native debugging. 00233 These units should set the table by calling 00234 windows_set_context_register_offsets. 00235 00236 One day we could read a reg, we could inspect the context we 00237 already have loaded, if it doesn't have the bit set that we need, 00238 we read that set of registers in using GetThreadContext. If the 00239 context already contains what we need, we just unpack it. Then to 00240 write a register, first we have to ensure that the context contains 00241 the other regs of the group, and then we copy the info in and set 00242 out bit. */ 00243 00244 static const int *mappings; 00245 00246 /* The function to use in order to determine whether a register is 00247 a segment register or not. */ 00248 static segment_register_p_ftype *segment_register_p; 00249 00250 /* This vector maps the target's idea of an exception (extracted 00251 from the DEBUG_EVENT structure) to GDB's idea. */ 00252 00253 struct xlate_exception 00254 { 00255 int them; 00256 enum gdb_signal us; 00257 }; 00258 00259 static const struct xlate_exception 00260 xlate[] = 00261 { 00262 {EXCEPTION_ACCESS_VIOLATION, GDB_SIGNAL_SEGV}, 00263 {STATUS_STACK_OVERFLOW, GDB_SIGNAL_SEGV}, 00264 {EXCEPTION_BREAKPOINT, GDB_SIGNAL_TRAP}, 00265 {DBG_CONTROL_C, GDB_SIGNAL_INT}, 00266 {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP}, 00267 {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE}, 00268 {-1, -1}}; 00269 00270 /* Set the MAPPINGS static global to OFFSETS. 00271 See the description of MAPPINGS for more details. */ 00272 00273 void 00274 windows_set_context_register_offsets (const int *offsets) 00275 { 00276 mappings = offsets; 00277 } 00278 00279 /* See windows-nat.h. */ 00280 00281 void 00282 windows_set_segment_register_p (segment_register_p_ftype *fun) 00283 { 00284 segment_register_p = fun; 00285 } 00286 00287 static void 00288 check (BOOL ok, const char *file, int line) 00289 { 00290 if (!ok) 00291 printf_filtered ("error return %s:%d was %u\n", file, line, 00292 (unsigned) GetLastError ()); 00293 } 00294 00295 /* Find a thread record given a thread id. If GET_CONTEXT is not 0, 00296 then also retrieve the context for this thread. If GET_CONTEXT is 00297 negative, then don't suspend the thread. */ 00298 static thread_info * 00299 thread_rec (DWORD id, int get_context) 00300 { 00301 thread_info *th; 00302 00303 for (th = &thread_head; (th = th->next) != NULL;) 00304 if (th->id == id) 00305 { 00306 if (!th->suspended && get_context) 00307 { 00308 if (get_context > 0 && id != current_event.dwThreadId) 00309 { 00310 if (SuspendThread (th->h) == (DWORD) -1) 00311 { 00312 DWORD err = GetLastError (); 00313 00314 warning (_("SuspendThread (tid=0x%x) failed." 00315 " (winerr %u)"), 00316 (unsigned) id, (unsigned) err); 00317 return NULL; 00318 } 00319 th->suspended = 1; 00320 } 00321 else if (get_context < 0) 00322 th->suspended = -1; 00323 th->reload_context = 1; 00324 } 00325 return th; 00326 } 00327 00328 return NULL; 00329 } 00330 00331 /* Add a thread to the thread list. */ 00332 static thread_info * 00333 windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) 00334 { 00335 thread_info *th; 00336 DWORD id; 00337 00338 gdb_assert (ptid_get_tid (ptid) != 0); 00339 00340 id = ptid_get_tid (ptid); 00341 00342 if ((th = thread_rec (id, FALSE))) 00343 return th; 00344 00345 th = XZALLOC (thread_info); 00346 th->id = id; 00347 th->h = h; 00348 th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb; 00349 th->next = thread_head.next; 00350 thread_head.next = th; 00351 add_thread (ptid); 00352 /* Set the debug registers for the new thread if they are used. */ 00353 if (debug_registers_used) 00354 { 00355 /* Only change the value of the debug registers. */ 00356 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS; 00357 CHECK (GetThreadContext (th->h, &th->context)); 00358 th->context.Dr0 = dr[0]; 00359 th->context.Dr1 = dr[1]; 00360 th->context.Dr2 = dr[2]; 00361 th->context.Dr3 = dr[3]; 00362 th->context.Dr6 = DR6_CLEAR_VALUE; 00363 th->context.Dr7 = dr[7]; 00364 CHECK (SetThreadContext (th->h, &th->context)); 00365 th->context.ContextFlags = 0; 00366 } 00367 return th; 00368 } 00369 00370 /* Clear out any old thread list and reintialize it to a 00371 pristine state. */ 00372 static void 00373 windows_init_thread_list (void) 00374 { 00375 thread_info *th = &thread_head; 00376 00377 DEBUG_EVENTS (("gdb: windows_init_thread_list\n")); 00378 init_thread_list (); 00379 while (th->next != NULL) 00380 { 00381 thread_info *here = th->next; 00382 th->next = here->next; 00383 xfree (here); 00384 } 00385 thread_head.next = NULL; 00386 } 00387 00388 /* Delete a thread from the list of threads. */ 00389 static void 00390 windows_delete_thread (ptid_t ptid, DWORD exit_code) 00391 { 00392 thread_info *th; 00393 DWORD id; 00394 00395 gdb_assert (ptid_get_tid (ptid) != 0); 00396 00397 id = ptid_get_tid (ptid); 00398 00399 if (info_verbose) 00400 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid)); 00401 else if (print_thread_events && id != main_thread_id) 00402 printf_unfiltered (_("[%s exited with code %u]\n"), 00403 target_pid_to_str (ptid), (unsigned) exit_code); 00404 delete_thread (ptid); 00405 00406 for (th = &thread_head; 00407 th->next != NULL && th->next->id != id; 00408 th = th->next) 00409 continue; 00410 00411 if (th->next != NULL) 00412 { 00413 thread_info *here = th->next; 00414 th->next = here->next; 00415 xfree (here); 00416 } 00417 } 00418 00419 static void 00420 do_windows_fetch_inferior_registers (struct regcache *regcache, int r) 00421 { 00422 char *context_offset = ((char *) ¤t_thread->context) + mappings[r]; 00423 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00424 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); 00425 long l; 00426 00427 if (!current_thread) 00428 return; /* Windows sometimes uses a non-existent thread id in its 00429 events. */ 00430 00431 if (current_thread->reload_context) 00432 { 00433 #ifdef __COPY_CONTEXT_SIZE 00434 if (have_saved_context) 00435 { 00436 /* Lie about where the program actually is stopped since 00437 cygwin has informed us that we should consider the signal 00438 to have occurred at another location which is stored in 00439 "saved_context. */ 00440 memcpy (¤t_thread->context, &saved_context, 00441 __COPY_CONTEXT_SIZE); 00442 have_saved_context = 0; 00443 } 00444 else 00445 #endif 00446 { 00447 thread_info *th = current_thread; 00448 th->context.ContextFlags = CONTEXT_DEBUGGER_DR; 00449 GetThreadContext (th->h, &th->context); 00450 /* Copy dr values from that thread. 00451 But only if there were not modified since last stop. 00452 PR gdb/2388 */ 00453 if (!debug_registers_changed) 00454 { 00455 dr[0] = th->context.Dr0; 00456 dr[1] = th->context.Dr1; 00457 dr[2] = th->context.Dr2; 00458 dr[3] = th->context.Dr3; 00459 dr[6] = th->context.Dr6; 00460 dr[7] = th->context.Dr7; 00461 } 00462 } 00463 current_thread->reload_context = 0; 00464 } 00465 00466 if (r == I387_FISEG_REGNUM (tdep)) 00467 { 00468 l = *((long *) context_offset) & 0xffff; 00469 regcache_raw_supply (regcache, r, (char *) &l); 00470 } 00471 else if (r == I387_FOP_REGNUM (tdep)) 00472 { 00473 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1); 00474 regcache_raw_supply (regcache, r, (char *) &l); 00475 } 00476 else if (segment_register_p (r)) 00477 { 00478 /* GDB treats segment registers as 32bit registers, but they are 00479 in fact only 16 bits long. Make sure we do not read extra 00480 bits from our source buffer. */ 00481 l = *((long *) context_offset) & 0xffff; 00482 regcache_raw_supply (regcache, r, (char *) &l); 00483 } 00484 else if (r >= 0) 00485 regcache_raw_supply (regcache, r, context_offset); 00486 else 00487 { 00488 for (r = 0; r < gdbarch_num_regs (gdbarch); r++) 00489 do_windows_fetch_inferior_registers (regcache, r); 00490 } 00491 } 00492 00493 static void 00494 windows_fetch_inferior_registers (struct target_ops *ops, 00495 struct regcache *regcache, int r) 00496 { 00497 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE); 00498 /* Check if current_thread exists. Windows sometimes uses a non-existent 00499 thread id in its events. */ 00500 if (current_thread) 00501 do_windows_fetch_inferior_registers (regcache, r); 00502 } 00503 00504 static void 00505 do_windows_store_inferior_registers (const struct regcache *regcache, int r) 00506 { 00507 if (!current_thread) 00508 /* Windows sometimes uses a non-existent thread id in its events. */; 00509 else if (r >= 0) 00510 regcache_raw_collect (regcache, r, 00511 ((char *) ¤t_thread->context) + mappings[r]); 00512 else 00513 { 00514 for (r = 0; r < gdbarch_num_regs (get_regcache_arch (regcache)); r++) 00515 do_windows_store_inferior_registers (regcache, r); 00516 } 00517 } 00518 00519 /* Store a new register value into the current thread context. */ 00520 static void 00521 windows_store_inferior_registers (struct target_ops *ops, 00522 struct regcache *regcache, int r) 00523 { 00524 current_thread = thread_rec (ptid_get_tid (inferior_ptid), TRUE); 00525 /* Check if current_thread exists. Windows sometimes uses a non-existent 00526 thread id in its events. */ 00527 if (current_thread) 00528 do_windows_store_inferior_registers (regcache, r); 00529 } 00530 00531 /* Get the name of a given module at given base address. If base_address 00532 is zero return the first loaded module (which is always the name of the 00533 executable). */ 00534 static int 00535 get_module_name (LPVOID base_address, char *dll_name_ret) 00536 { 00537 DWORD len; 00538 MODULEINFO mi; 00539 int i; 00540 HMODULE dh_buf[1]; 00541 HMODULE *DllHandle = dh_buf; /* Set to temporary storage for 00542 initial query. */ 00543 DWORD cbNeeded; 00544 #ifdef __CYGWIN__ 00545 cygwin_buf_t pathbuf[__PMAX]; /* Temporary storage prior to converting to 00546 posix form. __PMAX is always enough 00547 as long as SO_NAME_MAX_PATH_SIZE is defined 00548 as 512. */ 00549 #endif 00550 00551 cbNeeded = 0; 00552 /* Find size of buffer needed to handle list of modules loaded in 00553 inferior. */ 00554 if (!EnumProcessModules (current_process_handle, DllHandle, 00555 sizeof (HMODULE), &cbNeeded) || !cbNeeded) 00556 goto failed; 00557 00558 /* Allocate correct amount of space for module list. */ 00559 DllHandle = (HMODULE *) alloca (cbNeeded); 00560 if (!DllHandle) 00561 goto failed; 00562 00563 /* Get the list of modules. */ 00564 if (!EnumProcessModules (current_process_handle, DllHandle, cbNeeded, 00565 &cbNeeded)) 00566 goto failed; 00567 00568 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++) 00569 { 00570 /* Get information on this module. */ 00571 if (!GetModuleInformation (current_process_handle, DllHandle[i], 00572 &mi, sizeof (mi))) 00573 error (_("Can't get module info")); 00574 00575 if (!base_address || mi.lpBaseOfDll == base_address) 00576 { 00577 /* Try to find the name of the given module. */ 00578 #ifdef __CYGWIN__ 00579 /* Cygwin prefers that the path be in /x/y/z format. */ 00580 len = GetModuleFileNameEx (current_process_handle, 00581 DllHandle[i], pathbuf, __PMAX); 00582 if (len == 0) 00583 error (_("Error getting dll name: %u."), 00584 (unsigned) GetLastError ()); 00585 if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, dll_name_ret, 00586 __PMAX) < 0) 00587 error (_("Error converting dll name to POSIX: %d."), errno); 00588 #else 00589 len = GetModuleFileNameEx (current_process_handle, 00590 DllHandle[i], dll_name_ret, __PMAX); 00591 if (len == 0) 00592 error (_("Error getting dll name: %u."), 00593 (unsigned) GetLastError ()); 00594 #endif 00595 return 1; /* success */ 00596 } 00597 } 00598 00599 failed: 00600 dll_name_ret[0] = '\0'; 00601 return 0; /* failure */ 00602 } 00603 00604 /* Encapsulate the information required in a call to 00605 symbol_file_add_args. */ 00606 struct safe_symbol_file_add_args 00607 { 00608 char *name; 00609 int from_tty; 00610 struct section_addr_info *addrs; 00611 int mainline; 00612 int flags; 00613 struct ui_file *err, *out; 00614 struct objfile *ret; 00615 }; 00616 00617 /* Maintain a linked list of "so" information. */ 00618 struct lm_info 00619 { 00620 LPVOID load_addr; 00621 }; 00622 00623 static struct so_list solib_start, *solib_end; 00624 00625 /* Call symbol_file_add with stderr redirected. We don't care if there 00626 are errors. */ 00627 static int 00628 safe_symbol_file_add_stub (void *argv) 00629 { 00630 #define p ((struct safe_symbol_file_add_args *) argv) 00631 const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0) 00632 | (p->mainline ? SYMFILE_MAINLINE : 0)); 00633 p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags); 00634 return !!p->ret; 00635 #undef p 00636 } 00637 00638 /* Restore gdb's stderr after calling symbol_file_add. */ 00639 static void 00640 safe_symbol_file_add_cleanup (void *p) 00641 { 00642 #define sp ((struct safe_symbol_file_add_args *)p) 00643 gdb_flush (gdb_stderr); 00644 gdb_flush (gdb_stdout); 00645 ui_file_delete (gdb_stderr); 00646 ui_file_delete (gdb_stdout); 00647 gdb_stderr = sp->err; 00648 gdb_stdout = sp->out; 00649 #undef sp 00650 } 00651 00652 /* symbol_file_add wrapper that prevents errors from being displayed. */ 00653 static struct objfile * 00654 safe_symbol_file_add (char *name, int from_tty, 00655 struct section_addr_info *addrs, 00656 int mainline, int flags) 00657 { 00658 struct safe_symbol_file_add_args p; 00659 struct cleanup *cleanup; 00660 00661 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p); 00662 00663 p.err = gdb_stderr; 00664 p.out = gdb_stdout; 00665 gdb_flush (gdb_stderr); 00666 gdb_flush (gdb_stdout); 00667 gdb_stderr = ui_file_new (); 00668 gdb_stdout = ui_file_new (); 00669 p.name = name; 00670 p.from_tty = from_tty; 00671 p.addrs = addrs; 00672 p.mainline = mainline; 00673 p.flags = flags; 00674 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR); 00675 00676 do_cleanups (cleanup); 00677 return p.ret; 00678 } 00679 00680 static struct so_list * 00681 windows_make_so (const char *name, LPVOID load_addr) 00682 { 00683 struct so_list *so; 00684 char *p; 00685 #ifndef __CYGWIN__ 00686 char buf[__PMAX]; 00687 char cwd[__PMAX]; 00688 WIN32_FIND_DATA w32_fd; 00689 HANDLE h = FindFirstFile(name, &w32_fd); 00690 00691 if (h == INVALID_HANDLE_VALUE) 00692 strcpy (buf, name); 00693 else 00694 { 00695 FindClose (h); 00696 strcpy (buf, name); 00697 if (GetCurrentDirectory (MAX_PATH + 1, cwd)) 00698 { 00699 p = strrchr (buf, '\\'); 00700 if (p) 00701 p[1] = '\0'; 00702 SetCurrentDirectory (buf); 00703 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p); 00704 SetCurrentDirectory (cwd); 00705 } 00706 } 00707 if (strcasecmp (buf, "ntdll.dll") == 0) 00708 { 00709 GetSystemDirectory (buf, sizeof (buf)); 00710 strcat (buf, "\\ntdll.dll"); 00711 } 00712 #else 00713 cygwin_buf_t buf[__PMAX]; 00714 00715 buf[0] = 0; 00716 if (access (name, F_OK) != 0) 00717 { 00718 if (strcasecmp (name, "ntdll.dll") == 0) 00719 #ifdef __USEWIDE 00720 { 00721 GetSystemDirectoryW (buf, sizeof (buf) / sizeof (wchar_t)); 00722 wcscat (buf, L"\\ntdll.dll"); 00723 } 00724 #else 00725 { 00726 GetSystemDirectoryA (buf, sizeof (buf) / sizeof (wchar_t)); 00727 strcat (buf, "\\ntdll.dll"); 00728 } 00729 #endif 00730 } 00731 #endif 00732 so = XZALLOC (struct so_list); 00733 so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); 00734 so->lm_info->load_addr = load_addr; 00735 strcpy (so->so_original_name, name); 00736 #ifndef __CYGWIN__ 00737 strcpy (so->so_name, buf); 00738 #else 00739 if (buf[0]) 00740 cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name, 00741 SO_NAME_MAX_PATH_SIZE); 00742 else 00743 { 00744 char *rname = realpath (name, NULL); 00745 if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE) 00746 { 00747 strcpy (so->so_name, rname); 00748 free (rname); 00749 } 00750 else 00751 error (_("dll path too long")); 00752 } 00753 /* Record cygwin1.dll .text start/end. */ 00754 p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1); 00755 if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0) 00756 { 00757 bfd *abfd; 00758 asection *text = NULL; 00759 CORE_ADDR text_vma; 00760 00761 abfd = gdb_bfd_open (so->so_name, "pei-i386", -1); 00762 00763 if (!abfd) 00764 return so; 00765 00766 if (bfd_check_format (abfd, bfd_object)) 00767 text = bfd_get_section_by_name (abfd, ".text"); 00768 00769 if (!text) 00770 { 00771 gdb_bfd_unref (abfd); 00772 return so; 00773 } 00774 00775 /* The symbols in a dll are offset by 0x1000, which is the 00776 offset from 0 of the first byte in an image - because of the 00777 file header and the section alignment. */ 00778 cygwin_load_start = (CORE_ADDR) (uintptr_t) ((char *) 00779 load_addr + 0x1000); 00780 cygwin_load_end = cygwin_load_start + bfd_section_size (abfd, text); 00781 00782 gdb_bfd_unref (abfd); 00783 } 00784 #endif 00785 00786 return so; 00787 } 00788 00789 static char * 00790 get_image_name (HANDLE h, void *address, int unicode) 00791 { 00792 #ifdef __CYGWIN__ 00793 static char buf[__PMAX]; 00794 #else 00795 static char buf[(2 * __PMAX) + 1]; 00796 #endif 00797 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); 00798 char *address_ptr; 00799 int len = 0; 00800 char b[2]; 00801 SIZE_T done; 00802 00803 /* Attempt to read the name of the dll that was detected. 00804 This is documented to work only when actively debugging 00805 a program. It will not work for attached processes. */ 00806 if (address == NULL) 00807 return NULL; 00808 00809 /* See if we could read the address of a string, and that the 00810 address isn't null. */ 00811 if (!ReadProcessMemory (h, address, &address_ptr, 00812 sizeof (address_ptr), &done) 00813 || done != sizeof (address_ptr) || !address_ptr) 00814 return NULL; 00815 00816 /* Find the length of the string. */ 00817 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) 00818 && (b[0] != 0 || b[size - 1] != 0) && done == size) 00819 continue; 00820 00821 if (!unicode) 00822 ReadProcessMemory (h, address_ptr, buf, len, &done); 00823 else 00824 { 00825 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR)); 00826 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), 00827 &done); 00828 #ifdef __CYGWIN__ 00829 wcstombs (buf, unicode_address, __PMAX); 00830 #else 00831 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf, 00832 0, 0); 00833 #endif 00834 } 00835 00836 return buf; 00837 } 00838 00839 /* Wait for child to do something. Return pid of child, or -1 in case 00840 of error; store status through argument pointer OURSTATUS. */ 00841 static int 00842 handle_load_dll (void *dummy) 00843 { 00844 LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll; 00845 char dll_buf[__PMAX]; 00846 char *dll_name = NULL; 00847 00848 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; 00849 00850 if (!get_module_name (event->lpBaseOfDll, dll_buf)) 00851 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0'; 00852 00853 dll_name = dll_buf; 00854 00855 if (*dll_name == '\0') 00856 dll_name = get_image_name (current_process_handle, 00857 event->lpImageName, event->fUnicode); 00858 if (!dll_name) 00859 return 1; 00860 00861 solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll); 00862 solib_end = solib_end->next; 00863 00864 DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name, 00865 host_address_to_string (solib_end->lm_info->load_addr))); 00866 00867 return 1; 00868 } 00869 00870 static void 00871 windows_free_so (struct so_list *so) 00872 { 00873 if (so->lm_info) 00874 xfree (so->lm_info); 00875 xfree (so); 00876 } 00877 00878 static int 00879 handle_unload_dll (void *dummy) 00880 { 00881 LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll; 00882 struct so_list *so; 00883 00884 for (so = &solib_start; so->next != NULL; so = so->next) 00885 if (so->next->lm_info->load_addr == lpBaseOfDll) 00886 { 00887 struct so_list *sodel = so->next; 00888 00889 so->next = sodel->next; 00890 if (!so->next) 00891 solib_end = so; 00892 DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name)); 00893 00894 windows_free_so (sodel); 00895 return 1; 00896 } 00897 00898 /* We did not find any DLL that was previously loaded at this address, 00899 so register a complaint. We do not report an error, because we have 00900 observed that this may be happening under some circumstances. For 00901 instance, running 32bit applications on x64 Windows causes us to receive 00902 4 mysterious UNLOAD_DLL_DEBUG_EVENTs during the startup phase (these 00903 events are apparently caused by the WOW layer, the interface between 00904 32bit and 64bit worlds). */ 00905 complaint (&symfile_complaints, _("dll starting at %s not found."), 00906 host_address_to_string (lpBaseOfDll)); 00907 00908 return 0; 00909 } 00910 00911 /* Clear list of loaded DLLs. */ 00912 static void 00913 windows_clear_solib (void) 00914 { 00915 solib_start.next = NULL; 00916 solib_end = &solib_start; 00917 } 00918 00919 /* Load DLL symbol info. */ 00920 static void 00921 dll_symbol_command (char *args, int from_tty) 00922 { 00923 int n; 00924 dont_repeat (); 00925 00926 if (args == NULL) 00927 error (_("dll-symbols requires a file name")); 00928 00929 n = strlen (args); 00930 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0) 00931 { 00932 char *newargs = (char *) alloca (n + 4 + 1); 00933 strcpy (newargs, args); 00934 strcat (newargs, ".dll"); 00935 args = newargs; 00936 } 00937 00938 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED); 00939 } 00940 00941 /* Handle DEBUG_STRING output from child process. 00942 Cygwin prepends its messages with a "cygwin:". Interpret this as 00943 a Cygwin signal. Otherwise just print the string as a warning. */ 00944 static int 00945 handle_output_debug_string (struct target_waitstatus *ourstatus) 00946 { 00947 char *s = NULL; 00948 int retval = 0; 00949 00950 if (!target_read_string 00951 ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData, 00952 &s, 1024, 0) 00953 || !s || !*s) 00954 /* nothing to do */; 00955 else if (strncmp (s, _CYGWIN_SIGNAL_STRING, 00956 sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0) 00957 { 00958 #ifdef __CYGWIN__ 00959 if (strncmp (s, "cYg", 3) != 0) 00960 #endif 00961 warning (("%s"), s); 00962 } 00963 #ifdef __COPY_CONTEXT_SIZE 00964 else 00965 { 00966 /* Got a cygwin signal marker. A cygwin signal is followed by 00967 the signal number itself and then optionally followed by the 00968 thread id and address to saved context within the DLL. If 00969 these are supplied, then the given thread is assumed to have 00970 issued the signal and the context from the thread is assumed 00971 to be stored at the given address in the inferior. Tell gdb 00972 to treat this like a real signal. */ 00973 char *p; 00974 int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0); 00975 int gotasig = gdb_signal_from_host (sig); 00976 00977 ourstatus->value.sig = gotasig; 00978 if (gotasig) 00979 { 00980 LPCVOID x; 00981 SIZE_T n; 00982 00983 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00984 retval = strtoul (p, &p, 0); 00985 if (!retval) 00986 retval = main_thread_id; 00987 else if ((x = (LPCVOID) (uintptr_t) strtoull (p, NULL, 0)) 00988 && ReadProcessMemory (current_process_handle, x, 00989 &saved_context, 00990 __COPY_CONTEXT_SIZE, &n) 00991 && n == __COPY_CONTEXT_SIZE) 00992 have_saved_context = 1; 00993 current_event.dwThreadId = retval; 00994 } 00995 } 00996 #endif 00997 00998 if (s) 00999 xfree (s); 01000 return retval; 01001 } 01002 01003 static int 01004 display_selector (HANDLE thread, DWORD sel) 01005 { 01006 LDT_ENTRY info; 01007 if (GetThreadSelectorEntry (thread, sel, &info)) 01008 { 01009 int base, limit; 01010 printf_filtered ("0x%03x: ", (unsigned) sel); 01011 if (!info.HighWord.Bits.Pres) 01012 { 01013 puts_filtered ("Segment not present\n"); 01014 return 0; 01015 } 01016 base = (info.HighWord.Bits.BaseHi << 24) + 01017 (info.HighWord.Bits.BaseMid << 16) 01018 + info.BaseLow; 01019 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow; 01020 if (info.HighWord.Bits.Granularity) 01021 limit = (limit << 12) | 0xfff; 01022 printf_filtered ("base=0x%08x limit=0x%08x", base, limit); 01023 if (info.HighWord.Bits.Default_Big) 01024 puts_filtered(" 32-bit "); 01025 else 01026 puts_filtered(" 16-bit "); 01027 switch ((info.HighWord.Bits.Type & 0xf) >> 1) 01028 { 01029 case 0: 01030 puts_filtered ("Data (Read-Only, Exp-up"); 01031 break; 01032 case 1: 01033 puts_filtered ("Data (Read/Write, Exp-up"); 01034 break; 01035 case 2: 01036 puts_filtered ("Unused segment ("); 01037 break; 01038 case 3: 01039 puts_filtered ("Data (Read/Write, Exp-down"); 01040 break; 01041 case 4: 01042 puts_filtered ("Code (Exec-Only, N.Conf"); 01043 break; 01044 case 5: 01045 puts_filtered ("Code (Exec/Read, N.Conf"); 01046 break; 01047 case 6: 01048 puts_filtered ("Code (Exec-Only, Conf"); 01049 break; 01050 case 7: 01051 puts_filtered ("Code (Exec/Read, Conf"); 01052 break; 01053 default: 01054 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type); 01055 } 01056 if ((info.HighWord.Bits.Type & 0x1) == 0) 01057 puts_filtered(", N.Acc"); 01058 puts_filtered (")\n"); 01059 if ((info.HighWord.Bits.Type & 0x10) == 0) 01060 puts_filtered("System selector "); 01061 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl); 01062 if (info.HighWord.Bits.Granularity) 01063 puts_filtered ("Page granular.\n"); 01064 else 01065 puts_filtered ("Byte granular.\n"); 01066 return 1; 01067 } 01068 else 01069 { 01070 DWORD err = GetLastError (); 01071 if (err == ERROR_NOT_SUPPORTED) 01072 printf_filtered ("Function not supported\n"); 01073 else 01074 printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel); 01075 return 0; 01076 } 01077 } 01078 01079 static void 01080 display_selectors (char * args, int from_tty) 01081 { 01082 if (!current_thread) 01083 { 01084 puts_filtered ("Impossible to display selectors now.\n"); 01085 return; 01086 } 01087 if (!args) 01088 { 01089 01090 puts_filtered ("Selector $cs\n"); 01091 display_selector (current_thread->h, 01092 current_thread->context.SegCs); 01093 puts_filtered ("Selector $ds\n"); 01094 display_selector (current_thread->h, 01095 current_thread->context.SegDs); 01096 puts_filtered ("Selector $es\n"); 01097 display_selector (current_thread->h, 01098 current_thread->context.SegEs); 01099 puts_filtered ("Selector $ss\n"); 01100 display_selector (current_thread->h, 01101 current_thread->context.SegSs); 01102 puts_filtered ("Selector $fs\n"); 01103 display_selector (current_thread->h, 01104 current_thread->context.SegFs); 01105 puts_filtered ("Selector $gs\n"); 01106 display_selector (current_thread->h, 01107 current_thread->context.SegGs); 01108 } 01109 else 01110 { 01111 int sel; 01112 sel = parse_and_eval_long (args); 01113 printf_filtered ("Selector \"%s\"\n",args); 01114 display_selector (current_thread->h, sel); 01115 } 01116 } 01117 01118 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \ 01119 printf_unfiltered ("gdb: Target exception %s at %s\n", x, \ 01120 host_address_to_string (\ 01121 current_event.u.Exception.ExceptionRecord.ExceptionAddress)) 01122 01123 static int 01124 handle_exception (struct target_waitstatus *ourstatus) 01125 { 01126 thread_info *th; 01127 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; 01128 01129 ourstatus->kind = TARGET_WAITKIND_STOPPED; 01130 01131 /* Record the context of the current thread. */ 01132 th = thread_rec (current_event.dwThreadId, -1); 01133 01134 switch (code) 01135 { 01136 case EXCEPTION_ACCESS_VIOLATION: 01137 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION"); 01138 ourstatus->value.sig = GDB_SIGNAL_SEGV; 01139 #ifdef __CYGWIN__ 01140 { 01141 /* See if the access violation happened within the cygwin DLL 01142 itself. Cygwin uses a kind of exception handling to deal 01143 with passed-in invalid addresses. gdb should not treat 01144 these as real SEGVs since they will be silently handled by 01145 cygwin. A real SEGV will (theoretically) be caught by 01146 cygwin later in the process and will be sent as a 01147 cygwin-specific-signal. So, ignore SEGVs if they show up 01148 within the text segment of the DLL itself. */ 01149 const char *fn; 01150 CORE_ADDR addr = (CORE_ADDR) (uintptr_t) 01151 current_event.u.Exception.ExceptionRecord.ExceptionAddress; 01152 01153 if ((!cygwin_exceptions && (addr >= cygwin_load_start 01154 && addr < cygwin_load_end)) 01155 || (find_pc_partial_function (addr, &fn, NULL, NULL) 01156 && strncmp (fn, "KERNEL32!IsBad", 01157 strlen ("KERNEL32!IsBad")) == 0)) 01158 return 0; 01159 } 01160 #endif 01161 break; 01162 case STATUS_STACK_OVERFLOW: 01163 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW"); 01164 ourstatus->value.sig = GDB_SIGNAL_SEGV; 01165 break; 01166 case STATUS_FLOAT_DENORMAL_OPERAND: 01167 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND"); 01168 ourstatus->value.sig = GDB_SIGNAL_FPE; 01169 break; 01170 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 01171 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); 01172 ourstatus->value.sig = GDB_SIGNAL_FPE; 01173 break; 01174 case STATUS_FLOAT_INEXACT_RESULT: 01175 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT"); 01176 ourstatus->value.sig = GDB_SIGNAL_FPE; 01177 break; 01178 case STATUS_FLOAT_INVALID_OPERATION: 01179 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION"); 01180 ourstatus->value.sig = GDB_SIGNAL_FPE; 01181 break; 01182 case STATUS_FLOAT_OVERFLOW: 01183 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW"); 01184 ourstatus->value.sig = GDB_SIGNAL_FPE; 01185 break; 01186 case STATUS_FLOAT_STACK_CHECK: 01187 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK"); 01188 ourstatus->value.sig = GDB_SIGNAL_FPE; 01189 break; 01190 case STATUS_FLOAT_UNDERFLOW: 01191 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW"); 01192 ourstatus->value.sig = GDB_SIGNAL_FPE; 01193 break; 01194 case STATUS_FLOAT_DIVIDE_BY_ZERO: 01195 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO"); 01196 ourstatus->value.sig = GDB_SIGNAL_FPE; 01197 break; 01198 case STATUS_INTEGER_DIVIDE_BY_ZERO: 01199 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO"); 01200 ourstatus->value.sig = GDB_SIGNAL_FPE; 01201 break; 01202 case STATUS_INTEGER_OVERFLOW: 01203 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW"); 01204 ourstatus->value.sig = GDB_SIGNAL_FPE; 01205 break; 01206 case EXCEPTION_BREAKPOINT: 01207 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT"); 01208 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01209 break; 01210 case DBG_CONTROL_C: 01211 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C"); 01212 ourstatus->value.sig = GDB_SIGNAL_INT; 01213 break; 01214 case DBG_CONTROL_BREAK: 01215 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK"); 01216 ourstatus->value.sig = GDB_SIGNAL_INT; 01217 break; 01218 case EXCEPTION_SINGLE_STEP: 01219 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP"); 01220 ourstatus->value.sig = GDB_SIGNAL_TRAP; 01221 break; 01222 case EXCEPTION_ILLEGAL_INSTRUCTION: 01223 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION"); 01224 ourstatus->value.sig = GDB_SIGNAL_ILL; 01225 break; 01226 case EXCEPTION_PRIV_INSTRUCTION: 01227 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION"); 01228 ourstatus->value.sig = GDB_SIGNAL_ILL; 01229 break; 01230 case EXCEPTION_NONCONTINUABLE_EXCEPTION: 01231 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); 01232 ourstatus->value.sig = GDB_SIGNAL_ILL; 01233 break; 01234 default: 01235 /* Treat unhandled first chance exceptions specially. */ 01236 if (current_event.u.Exception.dwFirstChance) 01237 return -1; 01238 printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n", 01239 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, 01240 host_address_to_string ( 01241 current_event.u.Exception.ExceptionRecord.ExceptionAddress)); 01242 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN; 01243 break; 01244 } 01245 exception_count++; 01246 last_sig = ourstatus->value.sig; 01247 return 1; 01248 } 01249 01250 /* Resume all artificially suspended threads if we are continuing 01251 execution. */ 01252 static BOOL 01253 windows_continue (DWORD continue_status, int id) 01254 { 01255 int i; 01256 thread_info *th; 01257 BOOL res; 01258 01259 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n", 01260 (unsigned) current_event.dwProcessId, 01261 (unsigned) current_event.dwThreadId, 01262 continue_status == DBG_CONTINUE ? 01263 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED")); 01264 01265 for (th = &thread_head; (th = th->next) != NULL;) 01266 if ((id == -1 || id == (int) th->id) 01267 && th->suspended) 01268 { 01269 if (debug_registers_changed) 01270 { 01271 th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS; 01272 th->context.Dr0 = dr[0]; 01273 th->context.Dr1 = dr[1]; 01274 th->context.Dr2 = dr[2]; 01275 th->context.Dr3 = dr[3]; 01276 th->context.Dr6 = DR6_CLEAR_VALUE; 01277 th->context.Dr7 = dr[7]; 01278 } 01279 if (th->context.ContextFlags) 01280 { 01281 CHECK (SetThreadContext (th->h, &th->context)); 01282 th->context.ContextFlags = 0; 01283 } 01284 if (th->suspended > 0) 01285 (void) ResumeThread (th->h); 01286 th->suspended = 0; 01287 } 01288 01289 res = ContinueDebugEvent (current_event.dwProcessId, 01290 current_event.dwThreadId, 01291 continue_status); 01292 01293 debug_registers_changed = 0; 01294 return res; 01295 } 01296 01297 /* Called in pathological case where Windows fails to send a 01298 CREATE_PROCESS_DEBUG_EVENT after an attach. */ 01299 static DWORD 01300 fake_create_process (void) 01301 { 01302 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, 01303 current_event.dwProcessId); 01304 if (current_process_handle != NULL) 01305 open_process_used = 1; 01306 else 01307 { 01308 error (_("OpenProcess call failed, GetLastError = %u"), 01309 (unsigned) GetLastError ()); 01310 /* We can not debug anything in that case. */ 01311 } 01312 main_thread_id = current_event.dwThreadId; 01313 current_thread = windows_add_thread ( 01314 ptid_build (current_event.dwProcessId, 0, 01315 current_event.dwThreadId), 01316 current_event.u.CreateThread.hThread, 01317 current_event.u.CreateThread.lpThreadLocalBase); 01318 return main_thread_id; 01319 } 01320 01321 static void 01322 windows_resume (struct target_ops *ops, 01323 ptid_t ptid, int step, enum gdb_signal sig) 01324 { 01325 thread_info *th; 01326 DWORD continue_status = DBG_CONTINUE; 01327 01328 /* A specific PTID means `step only this thread id'. */ 01329 int resume_all = ptid_equal (ptid, minus_one_ptid); 01330 01331 /* If we're continuing all threads, it's the current inferior that 01332 should be handled specially. */ 01333 if (resume_all) 01334 ptid = inferior_ptid; 01335 01336 if (sig != GDB_SIGNAL_0) 01337 { 01338 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT) 01339 { 01340 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig)); 01341 } 01342 else if (sig == last_sig) 01343 continue_status = DBG_EXCEPTION_NOT_HANDLED; 01344 else 01345 #if 0 01346 /* This code does not seem to work, because 01347 the kernel does probably not consider changes in the ExceptionRecord 01348 structure when passing the exception to the inferior. 01349 Note that this seems possible in the exception handler itself. */ 01350 { 01351 int i; 01352 for (i = 0; xlate[i].them != -1; i++) 01353 if (xlate[i].us == sig) 01354 { 01355 current_event.u.Exception.ExceptionRecord.ExceptionCode 01356 = xlate[i].them; 01357 continue_status = DBG_EXCEPTION_NOT_HANDLED; 01358 break; 01359 } 01360 if (continue_status == DBG_CONTINUE) 01361 { 01362 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig)); 01363 } 01364 } 01365 #endif 01366 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n", 01367 last_sig)); 01368 } 01369 01370 last_sig = GDB_SIGNAL_0; 01371 01372 DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=%ld, step=%d, sig=%d);\n", 01373 ptid_get_pid (ptid), ptid_get_tid (ptid), step, sig)); 01374 01375 /* Get context for currently selected thread. */ 01376 th = thread_rec (ptid_get_tid (inferior_ptid), FALSE); 01377 if (th) 01378 { 01379 if (step) 01380 { 01381 /* Single step by setting t bit. */ 01382 struct regcache *regcache = get_current_regcache (); 01383 struct gdbarch *gdbarch = get_regcache_arch (regcache); 01384 windows_fetch_inferior_registers (ops, regcache, 01385 gdbarch_ps_regnum (gdbarch)); 01386 th->context.EFlags |= FLAG_TRACE_BIT; 01387 } 01388 01389 if (th->context.ContextFlags) 01390 { 01391 if (debug_registers_changed) 01392 { 01393 th->context.Dr0 = dr[0]; 01394 th->context.Dr1 = dr[1]; 01395 th->context.Dr2 = dr[2]; 01396 th->context.Dr3 = dr[3]; 01397 th->context.Dr6 = DR6_CLEAR_VALUE; 01398 th->context.Dr7 = dr[7]; 01399 } 01400 CHECK (SetThreadContext (th->h, &th->context)); 01401 th->context.ContextFlags = 0; 01402 } 01403 } 01404 01405 /* Allow continuing with the same signal that interrupted us. 01406 Otherwise complain. */ 01407 01408 if (resume_all) 01409 windows_continue (continue_status, -1); 01410 else 01411 windows_continue (continue_status, ptid_get_tid (ptid)); 01412 } 01413 01414 /* Ctrl-C handler used when the inferior is not run in the same console. The 01415 handler is in charge of interrupting the inferior using DebugBreakProcess. 01416 Note that this function is not available prior to Windows XP. In this case 01417 we emit a warning. */ 01418 static BOOL WINAPI 01419 ctrl_c_handler (DWORD event_type) 01420 { 01421 const int attach_flag = current_inferior ()->attach_flag; 01422 01423 /* Only handle Ctrl-C and Ctrl-Break events. Ignore others. */ 01424 if (event_type != CTRL_C_EVENT && event_type != CTRL_BREAK_EVENT) 01425 return FALSE; 01426 01427 /* If the inferior and the debugger share the same console, do nothing as 01428 the inferior has also received the Ctrl-C event. */ 01429 if (!new_console && !attach_flag) 01430 return TRUE; 01431 01432 if (!DebugBreakProcess (current_process_handle)) 01433 warning (_("Could not interrupt program. " 01434 "Press Ctrl-c in the program console.")); 01435 01436 /* Return true to tell that Ctrl-C has been handled. */ 01437 return TRUE; 01438 } 01439 01440 /* Get the next event from the child. Return 1 if the event requires 01441 handling by WFI (or whatever). */ 01442 static int 01443 get_windows_debug_event (struct target_ops *ops, 01444 int pid, struct target_waitstatus *ourstatus) 01445 { 01446 BOOL debug_event; 01447 DWORD continue_status, event_code; 01448 thread_info *th; 01449 static thread_info dummy_thread_info; 01450 int retval = 0; 01451 01452 last_sig = GDB_SIGNAL_0; 01453 01454 if (!(debug_event = WaitForDebugEvent (¤t_event, 1000))) 01455 goto out; 01456 01457 event_count++; 01458 continue_status = DBG_CONTINUE; 01459 01460 event_code = current_event.dwDebugEventCode; 01461 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 01462 th = NULL; 01463 have_saved_context = 0; 01464 01465 switch (event_code) 01466 { 01467 case CREATE_THREAD_DEBUG_EVENT: 01468 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01469 (unsigned) current_event.dwProcessId, 01470 (unsigned) current_event.dwThreadId, 01471 "CREATE_THREAD_DEBUG_EVENT")); 01472 if (saw_create != 1) 01473 { 01474 struct inferior *inf; 01475 inf = find_inferior_pid (current_event.dwProcessId); 01476 if (!saw_create && inf->attach_flag) 01477 { 01478 /* Kludge around a Windows bug where first event is a create 01479 thread event. Caused when attached process does not have 01480 a main thread. */ 01481 retval = fake_create_process (); 01482 if (retval) 01483 saw_create++; 01484 } 01485 break; 01486 } 01487 /* Record the existence of this thread. */ 01488 retval = current_event.dwThreadId; 01489 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, 01490 current_event.dwThreadId), 01491 current_event.u.CreateThread.hThread, 01492 current_event.u.CreateThread.lpThreadLocalBase); 01493 01494 break; 01495 01496 case EXIT_THREAD_DEBUG_EVENT: 01497 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01498 (unsigned) current_event.dwProcessId, 01499 (unsigned) current_event.dwThreadId, 01500 "EXIT_THREAD_DEBUG_EVENT")); 01501 01502 if (current_event.dwThreadId != main_thread_id) 01503 { 01504 windows_delete_thread (ptid_build (current_event.dwProcessId, 0, 01505 current_event.dwThreadId), 01506 current_event.u.ExitThread.dwExitCode); 01507 th = &dummy_thread_info; 01508 } 01509 break; 01510 01511 case CREATE_PROCESS_DEBUG_EVENT: 01512 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01513 (unsigned) current_event.dwProcessId, 01514 (unsigned) current_event.dwThreadId, 01515 "CREATE_PROCESS_DEBUG_EVENT")); 01516 CloseHandle (current_event.u.CreateProcessInfo.hFile); 01517 if (++saw_create != 1) 01518 break; 01519 01520 current_process_handle = current_event.u.CreateProcessInfo.hProcess; 01521 if (main_thread_id) 01522 windows_delete_thread (ptid_build (current_event.dwProcessId, 0, 01523 main_thread_id), 01524 0); 01525 main_thread_id = current_event.dwThreadId; 01526 /* Add the main thread. */ 01527 th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, 01528 current_event.dwThreadId), 01529 current_event.u.CreateProcessInfo.hThread, 01530 current_event.u.CreateProcessInfo.lpThreadLocalBase); 01531 retval = current_event.dwThreadId; 01532 break; 01533 01534 case EXIT_PROCESS_DEBUG_EVENT: 01535 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01536 (unsigned) current_event.dwProcessId, 01537 (unsigned) current_event.dwThreadId, 01538 "EXIT_PROCESS_DEBUG_EVENT")); 01539 if (!windows_initialization_done) 01540 { 01541 target_terminal_ours (); 01542 target_mourn_inferior (); 01543 error (_("During startup program exited with code 0x%x."), 01544 (unsigned int) current_event.u.ExitProcess.dwExitCode); 01545 } 01546 else if (saw_create == 1) 01547 { 01548 ourstatus->kind = TARGET_WAITKIND_EXITED; 01549 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; 01550 retval = main_thread_id; 01551 } 01552 break; 01553 01554 case LOAD_DLL_DEBUG_EVENT: 01555 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01556 (unsigned) current_event.dwProcessId, 01557 (unsigned) current_event.dwThreadId, 01558 "LOAD_DLL_DEBUG_EVENT")); 01559 CloseHandle (current_event.u.LoadDll.hFile); 01560 if (saw_create != 1) 01561 break; 01562 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); 01563 ourstatus->kind = TARGET_WAITKIND_LOADED; 01564 ourstatus->value.integer = 0; 01565 retval = main_thread_id; 01566 break; 01567 01568 case UNLOAD_DLL_DEBUG_EVENT: 01569 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01570 (unsigned) current_event.dwProcessId, 01571 (unsigned) current_event.dwThreadId, 01572 "UNLOAD_DLL_DEBUG_EVENT")); 01573 if (saw_create != 1) 01574 break; 01575 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); 01576 ourstatus->kind = TARGET_WAITKIND_LOADED; 01577 ourstatus->value.integer = 0; 01578 retval = main_thread_id; 01579 break; 01580 01581 case EXCEPTION_DEBUG_EVENT: 01582 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01583 (unsigned) current_event.dwProcessId, 01584 (unsigned) current_event.dwThreadId, 01585 "EXCEPTION_DEBUG_EVENT")); 01586 if (saw_create != 1) 01587 break; 01588 switch (handle_exception (ourstatus)) 01589 { 01590 case 0: 01591 continue_status = DBG_EXCEPTION_NOT_HANDLED; 01592 break; 01593 case 1: 01594 retval = current_event.dwThreadId; 01595 break; 01596 case -1: 01597 last_sig = 1; 01598 continue_status = -1; 01599 break; 01600 } 01601 break; 01602 01603 case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */ 01604 DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n", 01605 (unsigned) current_event.dwProcessId, 01606 (unsigned) current_event.dwThreadId, 01607 "OUTPUT_DEBUG_STRING_EVENT")); 01608 if (saw_create != 1) 01609 break; 01610 retval = handle_output_debug_string (ourstatus); 01611 break; 01612 01613 default: 01614 if (saw_create != 1) 01615 break; 01616 printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n", 01617 (unsigned) current_event.dwProcessId, 01618 (unsigned) current_event.dwThreadId); 01619 printf_unfiltered (" unknown event code %u\n", 01620 (unsigned) current_event.dwDebugEventCode); 01621 break; 01622 } 01623 01624 if (!retval || saw_create != 1) 01625 { 01626 if (continue_status == -1) 01627 windows_resume (ops, minus_one_ptid, 0, 1); 01628 else 01629 CHECK (windows_continue (continue_status, -1)); 01630 } 01631 else 01632 { 01633 inferior_ptid = ptid_build (current_event.dwProcessId, 0, 01634 retval); 01635 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); 01636 } 01637 01638 out: 01639 return retval; 01640 } 01641 01642 /* Wait for interesting events to occur in the target process. */ 01643 static ptid_t 01644 windows_wait (struct target_ops *ops, 01645 ptid_t ptid, struct target_waitstatus *ourstatus, int options) 01646 { 01647 int pid = -1; 01648 01649 target_terminal_ours (); 01650 01651 /* We loop when we get a non-standard exception rather than return 01652 with a SPURIOUS because resume can try and step or modify things, 01653 which needs a current_thread->h. But some of these exceptions mark 01654 the birth or death of threads, which mean that the current thread 01655 isn't necessarily what you think it is. */ 01656 01657 while (1) 01658 { 01659 int retval; 01660 01661 /* If the user presses Ctrl-c while the debugger is waiting 01662 for an event, he expects the debugger to interrupt his program 01663 and to get the prompt back. There are two possible situations: 01664 01665 - The debugger and the program do not share the console, in 01666 which case the Ctrl-c event only reached the debugger. 01667 In that case, the ctrl_c handler will take care of interrupting 01668 the inferior. Note that this case is working starting with 01669 Windows XP. For Windows 2000, Ctrl-C should be pressed in the 01670 inferior console. 01671 01672 - The debugger and the program share the same console, in which 01673 case both debugger and inferior will receive the Ctrl-c event. 01674 In that case the ctrl_c handler will ignore the event, as the 01675 Ctrl-c event generated inside the inferior will trigger the 01676 expected debug event. 01677 01678 FIXME: brobecker/2008-05-20: If the inferior receives the 01679 signal first and the delay until GDB receives that signal 01680 is sufficiently long, GDB can sometimes receive the SIGINT 01681 after we have unblocked the CTRL+C handler. This would 01682 lead to the debugger stopping prematurely while handling 01683 the new-thread event that comes with the handling of the SIGINT 01684 inside the inferior, and then stop again immediately when 01685 the user tries to resume the execution in the inferior. 01686 This is a classic race that we should try to fix one day. */ 01687 SetConsoleCtrlHandler (&ctrl_c_handler, TRUE); 01688 retval = get_windows_debug_event (ops, pid, ourstatus); 01689 SetConsoleCtrlHandler (&ctrl_c_handler, FALSE); 01690 01691 if (retval) 01692 return ptid_build (current_event.dwProcessId, 0, retval); 01693 else 01694 { 01695 int detach = 0; 01696 01697 if (deprecated_ui_loop_hook != NULL) 01698 detach = deprecated_ui_loop_hook (0); 01699 01700 if (detach) 01701 windows_kill_inferior (ops); 01702 } 01703 } 01704 } 01705 01706 static void 01707 do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) 01708 { 01709 extern int stop_after_trap; 01710 int i; 01711 struct inferior *inf; 01712 struct thread_info *tp; 01713 01714 last_sig = GDB_SIGNAL_0; 01715 event_count = 0; 01716 exception_count = 0; 01717 open_process_used = 0; 01718 debug_registers_changed = 0; 01719 debug_registers_used = 0; 01720 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++) 01721 dr[i] = 0; 01722 #ifdef __CYGWIN__ 01723 cygwin_load_start = cygwin_load_end = 0; 01724 #endif 01725 current_event.dwProcessId = pid; 01726 memset (¤t_event, 0, sizeof (current_event)); 01727 push_target (ops); 01728 disable_breakpoints_in_shlibs (); 01729 windows_clear_solib (); 01730 clear_proceed_status (); 01731 init_wait_for_inferior (); 01732 01733 inf = current_inferior (); 01734 inferior_appeared (inf, pid); 01735 inf->attach_flag = attaching; 01736 01737 /* Make the new process the current inferior, so terminal handling 01738 can rely on it. When attaching, we don't know about any thread 01739 id here, but that's OK --- nothing should be referencing the 01740 current thread until we report an event out of windows_wait. */ 01741 inferior_ptid = pid_to_ptid (pid); 01742 01743 terminal_init_inferior_with_pgrp (pid); 01744 target_terminal_inferior (); 01745 01746 windows_initialization_done = 0; 01747 inf->control.stop_soon = STOP_QUIETLY; 01748 while (1) 01749 { 01750 stop_after_trap = 1; 01751 wait_for_inferior (); 01752 tp = inferior_thread (); 01753 if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP) 01754 resume (0, tp->suspend.stop_signal); 01755 else 01756 break; 01757 } 01758 01759 windows_initialization_done = 1; 01760 inf->control.stop_soon = NO_STOP_QUIETLY; 01761 stop_after_trap = 0; 01762 return; 01763 } 01764 01765 /* Try to set or remove a user privilege to the current process. Return -1 01766 if that fails, the previous setting of that privilege otherwise. 01767 01768 This code is copied from the Cygwin source code and rearranged to allow 01769 dynamically loading of the needed symbols from advapi32 which is only 01770 available on NT/2K/XP. */ 01771 static int 01772 set_process_privilege (const char *privilege, BOOL enable) 01773 { 01774 HANDLE token_hdl = NULL; 01775 LUID restore_priv; 01776 TOKEN_PRIVILEGES new_priv, orig_priv; 01777 int ret = -1; 01778 DWORD size; 01779 01780 if (!OpenProcessToken (GetCurrentProcess (), 01781 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 01782 &token_hdl)) 01783 goto out; 01784 01785 if (!LookupPrivilegeValueA (NULL, privilege, &restore_priv)) 01786 goto out; 01787 01788 new_priv.PrivilegeCount = 1; 01789 new_priv.Privileges[0].Luid = restore_priv; 01790 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0; 01791 01792 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv, 01793 sizeof orig_priv, &orig_priv, &size)) 01794 goto out; 01795 #if 0 01796 /* Disabled, otherwise every `attach' in an unprivileged user session 01797 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in 01798 windows_attach(). */ 01799 /* AdjustTokenPrivileges returns TRUE even if the privilege could not 01800 be enabled. GetLastError () returns an correct error code, though. */ 01801 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED) 01802 goto out; 01803 #endif 01804 01805 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0; 01806 01807 out: 01808 if (token_hdl) 01809 CloseHandle (token_hdl); 01810 01811 return ret; 01812 } 01813 01814 /* Attach to process PID, then initialize for debugging it. */ 01815 static void 01816 windows_attach (struct target_ops *ops, char *args, int from_tty) 01817 { 01818 BOOL ok; 01819 DWORD pid; 01820 01821 pid = parse_pid_to_attach (args); 01822 01823 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0) 01824 { 01825 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n"); 01826 printf_unfiltered ("This can cause attach to " 01827 "fail on Windows NT/2K/XP\n"); 01828 } 01829 01830 windows_init_thread_list (); 01831 ok = DebugActiveProcess (pid); 01832 saw_create = 0; 01833 01834 #ifdef __CYGWIN__ 01835 if (!ok) 01836 { 01837 /* Try fall back to Cygwin pid. */ 01838 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid); 01839 01840 if (pid > 0) 01841 ok = DebugActiveProcess (pid); 01842 } 01843 #endif 01844 01845 if (!ok) 01846 error (_("Can't attach to process.")); 01847 01848 DebugSetProcessKillOnExit (FALSE); 01849 01850 if (from_tty) 01851 { 01852 char *exec_file = (char *) get_exec_file (0); 01853 01854 if (exec_file) 01855 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, 01856 target_pid_to_str (pid_to_ptid (pid))); 01857 else 01858 printf_unfiltered ("Attaching to %s\n", 01859 target_pid_to_str (pid_to_ptid (pid))); 01860 01861 gdb_flush (gdb_stdout); 01862 } 01863 01864 do_initial_windows_stuff (ops, pid, 1); 01865 target_terminal_ours (); 01866 } 01867 01868 static void 01869 windows_detach (struct target_ops *ops, char *args, int from_tty) 01870 { 01871 int detached = 1; 01872 01873 ptid_t ptid = {-1}; 01874 windows_resume (ops, ptid, 0, GDB_SIGNAL_0); 01875 01876 if (!DebugActiveProcessStop (current_event.dwProcessId)) 01877 { 01878 error (_("Can't detach process %u (error %u)"), 01879 (unsigned) current_event.dwProcessId, (unsigned) GetLastError ()); 01880 detached = 0; 01881 } 01882 DebugSetProcessKillOnExit (FALSE); 01883 01884 if (detached && from_tty) 01885 { 01886 char *exec_file = get_exec_file (0); 01887 if (exec_file == 0) 01888 exec_file = ""; 01889 printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file, 01890 (unsigned) current_event.dwProcessId); 01891 gdb_flush (gdb_stdout); 01892 } 01893 01894 i386_cleanup_dregs (); 01895 inferior_ptid = null_ptid; 01896 detach_inferior (current_event.dwProcessId); 01897 01898 unpush_target (ops); 01899 } 01900 01901 static char * 01902 windows_pid_to_exec_file (int pid) 01903 { 01904 static char path[__PMAX]; 01905 #ifdef __CYGWIN__ 01906 /* Try to find exe name as symlink target of /proc/<pid>/exe. */ 01907 int nchars; 01908 char procexe[sizeof ("/proc/4294967295/exe")]; 01909 01910 xsnprintf (procexe, sizeof (procexe), "/proc/%u/exe", pid); 01911 nchars = readlink (procexe, path, sizeof(path)); 01912 if (nchars > 0 && nchars < sizeof (path)) 01913 { 01914 path[nchars] = '\0'; /* Got it */ 01915 return path; 01916 } 01917 #endif 01918 01919 /* If we get here then either Cygwin is hosed, this isn't a Cygwin version 01920 of gdb, or we're trying to debug a non-Cygwin windows executable. */ 01921 if (!get_module_name (0, path)) 01922 path[0] = '\0'; 01923 01924 return path; 01925 } 01926 01927 /* Print status information about what we're accessing. */ 01928 01929 static void 01930 windows_files_info (struct target_ops *ignore) 01931 { 01932 struct inferior *inf = current_inferior (); 01933 01934 printf_unfiltered ("\tUsing the running image of %s %s.\n", 01935 inf->attach_flag ? "attached" : "child", 01936 target_pid_to_str (inferior_ptid)); 01937 } 01938 01939 static void 01940 windows_open (char *arg, int from_tty) 01941 { 01942 error (_("Use the \"run\" command to start a Unix child process.")); 01943 } 01944 01945 /* Modify CreateProcess parameters for use of a new separate console. 01946 Parameters are: 01947 *FLAGS: DWORD parameter for general process creation flags. 01948 *SI: STARTUPINFO structure, for which the console window size and 01949 console buffer size is filled in if GDB is running in a console. 01950 to create the new console. 01951 The size of the used font is not available on all versions of 01952 Windows OS. Furthermore, the current font might not be the default 01953 font, but this is still better than before. 01954 If the windows and buffer sizes are computed, 01955 SI->DWFLAGS is changed so that this information is used 01956 by CreateProcess function. */ 01957 01958 static void 01959 windows_set_console_info (STARTUPINFO *si, DWORD *flags) 01960 { 01961 HANDLE hconsole = CreateFile ("CONOUT$", GENERIC_READ | GENERIC_WRITE, 01962 FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); 01963 01964 if (hconsole != INVALID_HANDLE_VALUE) 01965 { 01966 CONSOLE_SCREEN_BUFFER_INFO sbinfo; 01967 COORD font_size; 01968 CONSOLE_FONT_INFO cfi; 01969 01970 GetCurrentConsoleFont (hconsole, FALSE, &cfi); 01971 font_size = GetConsoleFontSize (hconsole, cfi.nFont); 01972 GetConsoleScreenBufferInfo(hconsole, &sbinfo); 01973 si->dwXSize = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1; 01974 si->dwYSize = sbinfo.srWindow.Bottom - sbinfo.srWindow.Top + 1; 01975 if (font_size.X) 01976 si->dwXSize *= font_size.X; 01977 else 01978 si->dwXSize *= 8; 01979 if (font_size.Y) 01980 si->dwYSize *= font_size.Y; 01981 else 01982 si->dwYSize *= 12; 01983 si->dwXCountChars = sbinfo.dwSize.X; 01984 si->dwYCountChars = sbinfo.dwSize.Y; 01985 si->dwFlags |= STARTF_USESIZE | STARTF_USECOUNTCHARS; 01986 } 01987 *flags |= CREATE_NEW_CONSOLE; 01988 } 01989 01990 #ifndef __CYGWIN__ 01991 /* Function called by qsort to sort environment strings. */ 01992 01993 static int 01994 envvar_cmp (const void *a, const void *b) 01995 { 01996 const char **p = (const char **) a; 01997 const char **q = (const char **) b; 01998 return strcasecmp (*p, *q); 01999 } 02000 #endif 02001 02002 #ifdef __CYGWIN__ 02003 static void 02004 clear_win32_environment (char **env) 02005 { 02006 int i; 02007 size_t len; 02008 wchar_t *copy = NULL, *equalpos; 02009 02010 for (i = 0; env[i] && *env[i]; i++) 02011 { 02012 len = mbstowcs (NULL, env[i], 0) + 1; 02013 copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t)); 02014 mbstowcs (copy, env[i], len); 02015 equalpos = wcschr (copy, L'='); 02016 if (equalpos) 02017 *equalpos = L'\0'; 02018 SetEnvironmentVariableW (copy, NULL); 02019 } 02020 xfree (copy); 02021 } 02022 #endif 02023 02024 /* Start an inferior windows child process and sets inferior_ptid to its pid. 02025 EXEC_FILE is the file to run. 02026 ALLARGS is a string containing the arguments to the program. 02027 ENV is the environment vector to pass. Errors reported with error(). */ 02028 02029 static void 02030 windows_create_inferior (struct target_ops *ops, char *exec_file, 02031 char *allargs, char **in_env, int from_tty) 02032 { 02033 STARTUPINFO si; 02034 #ifdef __CYGWIN__ 02035 cygwin_buf_t real_path[__PMAX]; 02036 cygwin_buf_t shell[__PMAX]; /* Path to shell */ 02037 const char *sh; 02038 cygwin_buf_t *toexec; 02039 cygwin_buf_t *cygallargs; 02040 cygwin_buf_t *args; 02041 char **old_env = NULL; 02042 PWCHAR w32_env; 02043 size_t len; 02044 int tty; 02045 int ostdin, ostdout, ostderr; 02046 #else 02047 char real_path[__PMAX]; 02048 char shell[__PMAX]; /* Path to shell */ 02049 char *toexec; 02050 char *args; 02051 size_t args_len; 02052 HANDLE tty; 02053 char *w32env; 02054 char *temp; 02055 size_t envlen; 02056 int i; 02057 size_t envsize; 02058 char **env; 02059 #endif 02060 PROCESS_INFORMATION pi; 02061 BOOL ret; 02062 DWORD flags = 0; 02063 const char *inferior_io_terminal = get_inferior_io_terminal (); 02064 02065 if (!exec_file) 02066 error (_("No executable specified, use `target exec'.")); 02067 02068 memset (&si, 0, sizeof (si)); 02069 si.cb = sizeof (si); 02070 02071 if (new_group) 02072 flags |= CREATE_NEW_PROCESS_GROUP; 02073 02074 if (new_console) 02075 windows_set_console_info (&si, &flags); 02076 02077 #ifdef __CYGWIN__ 02078 if (!useshell) 02079 { 02080 flags |= DEBUG_ONLY_THIS_PROCESS; 02081 if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, exec_file, real_path, 02082 __PMAX * sizeof (cygwin_buf_t)) < 0) 02083 error (_("Error starting executable: %d"), errno); 02084 toexec = real_path; 02085 #ifdef __USEWIDE 02086 len = mbstowcs (NULL, allargs, 0) + 1; 02087 if (len == (size_t) -1) 02088 error (_("Error starting executable: %d"), errno); 02089 cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t)); 02090 mbstowcs (cygallargs, allargs, len); 02091 #else 02092 cygallargs = allargs; 02093 #endif 02094 } 02095 else 02096 { 02097 sh = getenv ("SHELL"); 02098 if (!sh) 02099 sh = "/bin/sh"; 02100 if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0) 02101 error (_("Error starting executable via shell: %d"), errno); 02102 #ifdef __USEWIDE 02103 len = sizeof (L" -c 'exec '") + mbstowcs (NULL, exec_file, 0) 02104 + mbstowcs (NULL, allargs, 0) + 2; 02105 cygallargs = (wchar_t *) alloca (len * sizeof (wchar_t)); 02106 swprintf (cygallargs, len, L" -c 'exec %s %s'", exec_file, allargs); 02107 #else 02108 len = (sizeof (" -c 'exec '") + strlen (exec_file) 02109 + strlen (allargs) + 2); 02110 cygallargs = (char *) alloca (len); 02111 xsnprintf (cygallargs, len, " -c 'exec %s %s'", exec_file, allargs); 02112 #endif 02113 toexec = shell; 02114 flags |= DEBUG_PROCESS; 02115 } 02116 02117 #ifdef __USEWIDE 02118 args = (cygwin_buf_t *) alloca ((wcslen (toexec) + wcslen (cygallargs) + 2) 02119 * sizeof (wchar_t)); 02120 wcscpy (args, toexec); 02121 wcscat (args, L" "); 02122 wcscat (args, cygallargs); 02123 #else 02124 args = (cygwin_buf_t *) alloca (strlen (toexec) + strlen (cygallargs) + 2); 02125 strcpy (args, toexec); 02126 strcat (args, " "); 02127 strcat (args, cygallargs); 02128 #endif 02129 02130 #ifdef CW_CVT_ENV_TO_WINENV 02131 /* First try to create a direct Win32 copy of the POSIX environment. */ 02132 w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env); 02133 if (w32_env != (PWCHAR) -1) 02134 flags |= CREATE_UNICODE_ENVIRONMENT; 02135 else 02136 /* If that fails, fall back to old method tweaking GDB's environment. */ 02137 #endif 02138 { 02139 /* Reset all Win32 environment variables to avoid leftover on next run. */ 02140 clear_win32_environment (environ); 02141 /* Prepare the environment vars for CreateProcess. */ 02142 old_env = environ; 02143 environ = in_env; 02144 cygwin_internal (CW_SYNC_WINENV); 02145 w32_env = NULL; 02146 } 02147 02148 if (!inferior_io_terminal) 02149 tty = ostdin = ostdout = ostderr = -1; 02150 else 02151 { 02152 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY); 02153 if (tty < 0) 02154 { 02155 print_sys_errmsg (inferior_io_terminal, errno); 02156 ostdin = ostdout = ostderr = -1; 02157 } 02158 else 02159 { 02160 ostdin = dup (0); 02161 ostdout = dup (1); 02162 ostderr = dup (2); 02163 dup2 (tty, 0); 02164 dup2 (tty, 1); 02165 dup2 (tty, 2); 02166 } 02167 } 02168 02169 windows_init_thread_list (); 02170 ret = CreateProcess (0, 02171 args, /* command line */ 02172 NULL, /* Security */ 02173 NULL, /* thread */ 02174 TRUE, /* inherit handles */ 02175 flags, /* start flags */ 02176 w32_env, /* environment */ 02177 NULL, /* current directory */ 02178 &si, 02179 &pi); 02180 if (w32_env) 02181 /* Just free the Win32 environment, if it could be created. */ 02182 free (w32_env); 02183 else 02184 { 02185 /* Reset all environment variables to avoid leftover on next run. */ 02186 clear_win32_environment (in_env); 02187 /* Restore normal GDB environment variables. */ 02188 environ = old_env; 02189 cygwin_internal (CW_SYNC_WINENV); 02190 } 02191 02192 if (tty >= 0) 02193 { 02194 close (tty); 02195 dup2 (ostdin, 0); 02196 dup2 (ostdout, 1); 02197 dup2 (ostderr, 2); 02198 close (ostdin); 02199 close (ostdout); 02200 close (ostderr); 02201 } 02202 #else 02203 toexec = exec_file; 02204 /* Build the command line, a space-separated list of tokens where 02205 the first token is the name of the module to be executed. 02206 To avoid ambiguities introduced by spaces in the module name, 02207 we quote it. */ 02208 args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2; 02209 args = alloca (args_len); 02210 xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs); 02211 02212 flags |= DEBUG_ONLY_THIS_PROCESS; 02213 02214 if (!inferior_io_terminal) 02215 tty = INVALID_HANDLE_VALUE; 02216 else 02217 { 02218 SECURITY_ATTRIBUTES sa; 02219 sa.nLength = sizeof(sa); 02220 sa.lpSecurityDescriptor = 0; 02221 sa.bInheritHandle = TRUE; 02222 tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE, 02223 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 02224 if (tty == INVALID_HANDLE_VALUE) 02225 warning (_("Warning: Failed to open TTY %s, error %#x."), 02226 inferior_io_terminal, (unsigned) GetLastError ()); 02227 else 02228 { 02229 si.hStdInput = tty; 02230 si.hStdOutput = tty; 02231 si.hStdError = tty; 02232 si.dwFlags |= STARTF_USESTDHANDLES; 02233 } 02234 } 02235 02236 /* CreateProcess takes the environment list as a null terminated set of 02237 strings (i.e. two nulls terminate the list). */ 02238 02239 /* Get total size for env strings. */ 02240 for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++) 02241 envlen += strlen (in_env[i]) + 1; 02242 02243 envsize = sizeof (in_env[0]) * (i + 1); 02244 env = (char **) alloca (envsize); 02245 memcpy (env, in_env, envsize); 02246 /* Windows programs expect the environment block to be sorted. */ 02247 qsort (env, i, sizeof (char *), envvar_cmp); 02248 02249 w32env = alloca (envlen + 1); 02250 02251 /* Copy env strings into new buffer. */ 02252 for (temp = w32env, i = 0; env[i] && *env[i]; i++) 02253 { 02254 strcpy (temp, env[i]); 02255 temp += strlen (temp) + 1; 02256 } 02257 02258 /* Final nil string to terminate new env. */ 02259 *temp = 0; 02260 02261 windows_init_thread_list (); 02262 ret = CreateProcessA (0, 02263 args, /* command line */ 02264 NULL, /* Security */ 02265 NULL, /* thread */ 02266 TRUE, /* inherit handles */ 02267 flags, /* start flags */ 02268 w32env, /* environment */ 02269 NULL, /* current directory */ 02270 &si, 02271 &pi); 02272 if (tty != INVALID_HANDLE_VALUE) 02273 CloseHandle (tty); 02274 #endif 02275 02276 if (!ret) 02277 error (_("Error creating process %s, (error %u)."), 02278 exec_file, (unsigned) GetLastError ()); 02279 02280 CloseHandle (pi.hThread); 02281 CloseHandle (pi.hProcess); 02282 02283 if (useshell && shell[0] != '\0') 02284 saw_create = -1; 02285 else 02286 saw_create = 0; 02287 02288 do_initial_windows_stuff (ops, pi.dwProcessId, 0); 02289 02290 /* windows_continue (DBG_CONTINUE, -1); */ 02291 } 02292 02293 static void 02294 windows_mourn_inferior (struct target_ops *ops) 02295 { 02296 (void) windows_continue (DBG_CONTINUE, -1); 02297 i386_cleanup_dregs(); 02298 if (open_process_used) 02299 { 02300 CHECK (CloseHandle (current_process_handle)); 02301 open_process_used = 0; 02302 } 02303 unpush_target (ops); 02304 generic_mourn_inferior (); 02305 } 02306 02307 /* Send a SIGINT to the process group. This acts just like the user typed a 02308 ^C on the controlling terminal. */ 02309 02310 static void 02311 windows_stop (ptid_t ptid) 02312 { 02313 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); 02314 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); 02315 registers_changed (); /* refresh register state */ 02316 } 02317 02318 /* Helper for windows_xfer_partial that handles memory transfers. 02319 Arguments are like target_xfer_partial. */ 02320 02321 static LONGEST 02322 windows_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf, 02323 ULONGEST memaddr, LONGEST len) 02324 { 02325 SIZE_T done = 0; 02326 BOOL success; 02327 DWORD lasterror = 0; 02328 02329 if (writebuf != NULL) 02330 { 02331 DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n", 02332 plongest (len), core_addr_to_string (memaddr))); 02333 success = WriteProcessMemory (current_process_handle, 02334 (LPVOID) (uintptr_t) memaddr, writebuf, 02335 len, &done); 02336 if (!success) 02337 lasterror = GetLastError (); 02338 FlushInstructionCache (current_process_handle, 02339 (LPCVOID) (uintptr_t) memaddr, len); 02340 } 02341 else 02342 { 02343 DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n", 02344 plongest (len), core_addr_to_string (memaddr))); 02345 success = ReadProcessMemory (current_process_handle, 02346 (LPCVOID) (uintptr_t) memaddr, readbuf, 02347 len, &done); 02348 if (!success) 02349 lasterror = GetLastError (); 02350 } 02351 if (!success && lasterror == ERROR_PARTIAL_COPY && done > 0) 02352 return done; 02353 else 02354 return success ? done : TARGET_XFER_E_IO; 02355 } 02356 02357 static void 02358 windows_kill_inferior (struct target_ops *ops) 02359 { 02360 CHECK (TerminateProcess (current_process_handle, 0)); 02361 02362 for (;;) 02363 { 02364 if (!windows_continue (DBG_CONTINUE, -1)) 02365 break; 02366 if (!WaitForDebugEvent (¤t_event, INFINITE)) 02367 break; 02368 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT) 02369 break; 02370 } 02371 02372 target_mourn_inferior (); /* Or just windows_mourn_inferior? */ 02373 } 02374 02375 static void 02376 windows_prepare_to_store (struct regcache *regcache) 02377 { 02378 /* Do nothing, since we can store individual regs. */ 02379 } 02380 02381 static int 02382 windows_can_run (void) 02383 { 02384 return 1; 02385 } 02386 02387 static void 02388 windows_close (void) 02389 { 02390 DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n", 02391 ptid_get_pid (inferior_ptid))); 02392 } 02393 02394 /* Convert pid to printable format. */ 02395 static char * 02396 windows_pid_to_str (struct target_ops *ops, ptid_t ptid) 02397 { 02398 static char buf[80]; 02399 02400 if (ptid_get_tid (ptid) != 0) 02401 { 02402 snprintf (buf, sizeof (buf), "Thread %d.0x%lx", 02403 ptid_get_pid (ptid), ptid_get_tid (ptid)); 02404 return buf; 02405 } 02406 02407 return normal_pid_to_str (ptid); 02408 } 02409 02410 static LONGEST 02411 windows_xfer_shared_libraries (struct target_ops *ops, 02412 enum target_object object, const char *annex, 02413 gdb_byte *readbuf, const gdb_byte *writebuf, 02414 ULONGEST offset, LONGEST len) 02415 { 02416 struct obstack obstack; 02417 const char *buf; 02418 LONGEST len_avail; 02419 struct so_list *so; 02420 02421 if (writebuf) 02422 return -1; 02423 02424 obstack_init (&obstack); 02425 obstack_grow_str (&obstack, "<library-list>\n"); 02426 for (so = solib_start.next; so; so = so->next) 02427 windows_xfer_shared_library (so->so_name, (CORE_ADDR) 02428 (uintptr_t) so->lm_info->load_addr, 02429 target_gdbarch (), &obstack); 02430 obstack_grow_str0 (&obstack, "</library-list>\n"); 02431 02432 buf = obstack_finish (&obstack); 02433 len_avail = strlen (buf); 02434 if (offset >= len_avail) 02435 len= 0; 02436 else 02437 { 02438 if (len > len_avail - offset) 02439 len = len_avail - offset; 02440 memcpy (readbuf, buf + offset, len); 02441 } 02442 02443 obstack_free (&obstack, NULL); 02444 return len; 02445 } 02446 02447 static LONGEST 02448 windows_xfer_partial (struct target_ops *ops, enum target_object object, 02449 const char *annex, gdb_byte *readbuf, 02450 const gdb_byte *writebuf, ULONGEST offset, LONGEST len) 02451 { 02452 switch (object) 02453 { 02454 case TARGET_OBJECT_MEMORY: 02455 return windows_xfer_memory (readbuf, writebuf, offset, len); 02456 02457 case TARGET_OBJECT_LIBRARIES: 02458 return windows_xfer_shared_libraries (ops, object, annex, readbuf, 02459 writebuf, offset, len); 02460 02461 default: 02462 if (ops->beneath != NULL) 02463 return ops->beneath->to_xfer_partial (ops->beneath, object, annex, 02464 readbuf, writebuf, offset, len); 02465 return -1; 02466 } 02467 } 02468 02469 /* Provide thread local base, i.e. Thread Information Block address. 02470 Returns 1 if ptid is found and sets *ADDR to thread_local_base. */ 02471 02472 static int 02473 windows_get_tib_address (ptid_t ptid, CORE_ADDR *addr) 02474 { 02475 thread_info *th; 02476 02477 th = thread_rec (ptid_get_tid (ptid), 0); 02478 if (th == NULL) 02479 return 0; 02480 02481 if (addr != NULL) 02482 *addr = th->thread_local_base; 02483 02484 return 1; 02485 } 02486 02487 static ptid_t 02488 windows_get_ada_task_ptid (long lwp, long thread) 02489 { 02490 return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp); 02491 } 02492 02493 static void 02494 init_windows_ops (void) 02495 { 02496 windows_ops.to_shortname = "child"; 02497 windows_ops.to_longname = "Win32 child process"; 02498 windows_ops.to_doc = "Win32 child process (started by the \"run\" command)."; 02499 windows_ops.to_open = windows_open; 02500 windows_ops.to_close = windows_close; 02501 windows_ops.to_attach = windows_attach; 02502 windows_ops.to_attach_no_wait = 1; 02503 windows_ops.to_detach = windows_detach; 02504 windows_ops.to_resume = windows_resume; 02505 windows_ops.to_wait = windows_wait; 02506 windows_ops.to_fetch_registers = windows_fetch_inferior_registers; 02507 windows_ops.to_store_registers = windows_store_inferior_registers; 02508 windows_ops.to_prepare_to_store = windows_prepare_to_store; 02509 windows_ops.to_xfer_partial = windows_xfer_partial; 02510 windows_ops.to_files_info = windows_files_info; 02511 windows_ops.to_insert_breakpoint = memory_insert_breakpoint; 02512 windows_ops.to_remove_breakpoint = memory_remove_breakpoint; 02513 windows_ops.to_terminal_init = terminal_init_inferior; 02514 windows_ops.to_terminal_inferior = terminal_inferior; 02515 windows_ops.to_terminal_ours_for_output = terminal_ours_for_output; 02516 windows_ops.to_terminal_ours = terminal_ours; 02517 windows_ops.to_terminal_save_ours = terminal_save_ours; 02518 windows_ops.to_terminal_info = child_terminal_info; 02519 windows_ops.to_kill = windows_kill_inferior; 02520 windows_ops.to_create_inferior = windows_create_inferior; 02521 windows_ops.to_mourn_inferior = windows_mourn_inferior; 02522 windows_ops.to_can_run = windows_can_run; 02523 windows_ops.to_thread_alive = windows_thread_alive; 02524 windows_ops.to_pid_to_str = windows_pid_to_str; 02525 windows_ops.to_stop = windows_stop; 02526 windows_ops.to_stratum = process_stratum; 02527 windows_ops.to_has_all_memory = default_child_has_all_memory; 02528 windows_ops.to_has_memory = default_child_has_memory; 02529 windows_ops.to_has_stack = default_child_has_stack; 02530 windows_ops.to_has_registers = default_child_has_registers; 02531 windows_ops.to_has_execution = default_child_has_execution; 02532 windows_ops.to_pid_to_exec_file = windows_pid_to_exec_file; 02533 windows_ops.to_get_ada_task_ptid = windows_get_ada_task_ptid; 02534 windows_ops.to_get_tib_address = windows_get_tib_address; 02535 02536 i386_use_watchpoints (&windows_ops); 02537 02538 i386_dr_low.set_control = cygwin_set_dr7; 02539 i386_dr_low.set_addr = cygwin_set_dr; 02540 i386_dr_low.get_addr = cygwin_get_dr; 02541 i386_dr_low.get_status = cygwin_get_dr6; 02542 i386_dr_low.get_control = cygwin_get_dr7; 02543 02544 /* i386_dr_low.debug_register_length field is set by 02545 calling i386_set_debug_register_length function 02546 in processor windows specific native file. */ 02547 02548 windows_ops.to_magic = OPS_MAGIC; 02549 } 02550 02551 static void 02552 set_windows_aliases (char *argv0) 02553 { 02554 add_info_alias ("dll", "sharedlibrary", 1); 02555 } 02556 02557 /* -Wmissing-prototypes */ 02558 extern initialize_file_ftype _initialize_windows_nat; 02559 02560 void 02561 _initialize_windows_nat (void) 02562 { 02563 struct cmd_list_element *c; 02564 02565 init_windows_ops (); 02566 02567 #ifdef __CYGWIN__ 02568 cygwin_internal (CW_SET_DOS_FILE_WARNING, 0); 02569 #endif 02570 02571 c = add_com ("dll-symbols", class_files, dll_symbol_command, 02572 _("Load dll library symbols from FILE.")); 02573 set_cmd_completer (c, filename_completer); 02574 02575 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1); 02576 02577 add_com_alias ("add-shared-symbol-files", "dll-symbols", class_alias, 1); 02578 02579 add_com_alias ("assf", "dll-symbols", class_alias, 1); 02580 02581 #ifdef __CYGWIN__ 02582 add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\ 02583 Set use of shell to start subprocess."), _("\ 02584 Show use of shell to start subprocess."), NULL, 02585 NULL, 02586 NULL, /* FIXME: i18n: */ 02587 &setlist, &showlist); 02588 02589 add_setshow_boolean_cmd ("cygwin-exceptions", class_support, 02590 &cygwin_exceptions, _("\ 02591 Break when an exception is detected in the Cygwin DLL itself."), _("\ 02592 Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL, 02593 NULL, 02594 NULL, /* FIXME: i18n: */ 02595 &setlist, &showlist); 02596 #endif 02597 02598 add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\ 02599 Set creation of new console when creating child process."), _("\ 02600 Show creation of new console when creating child process."), NULL, 02601 NULL, 02602 NULL, /* FIXME: i18n: */ 02603 &setlist, &showlist); 02604 02605 add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\ 02606 Set creation of new group when creating child process."), _("\ 02607 Show creation of new group when creating child process."), NULL, 02608 NULL, 02609 NULL, /* FIXME: i18n: */ 02610 &setlist, &showlist); 02611 02612 add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\ 02613 Set whether to display execution in child process."), _("\ 02614 Show whether to display execution in child process."), NULL, 02615 NULL, 02616 NULL, /* FIXME: i18n: */ 02617 &setlist, &showlist); 02618 02619 add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\ 02620 Set whether to display kernel events in child process."), _("\ 02621 Show whether to display kernel events in child process."), NULL, 02622 NULL, 02623 NULL, /* FIXME: i18n: */ 02624 &setlist, &showlist); 02625 02626 add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\ 02627 Set whether to display memory accesses in child process."), _("\ 02628 Show whether to display memory accesses in child process."), NULL, 02629 NULL, 02630 NULL, /* FIXME: i18n: */ 02631 &setlist, &showlist); 02632 02633 add_setshow_boolean_cmd ("debugexceptions", class_support, 02634 &debug_exceptions, _("\ 02635 Set whether to display kernel exceptions in child process."), _("\ 02636 Show whether to display kernel exceptions in child process."), NULL, 02637 NULL, 02638 NULL, /* FIXME: i18n: */ 02639 &setlist, &showlist); 02640 02641 init_w32_command_list (); 02642 02643 add_cmd ("selector", class_info, display_selectors, 02644 _("Display selectors infos."), 02645 &info_w32_cmdlist); 02646 add_target (&windows_ops); 02647 deprecated_init_ui_hook = set_windows_aliases; 02648 } 02649 02650 /* Hardware watchpoint support, adapted from go32-nat.c code. */ 02651 02652 /* Pass the address ADDR to the inferior in the I'th debug register. 02653 Here we just store the address in dr array, the registers will be 02654 actually set up when windows_continue is called. */ 02655 static void 02656 cygwin_set_dr (int i, CORE_ADDR addr) 02657 { 02658 if (i < 0 || i > 3) 02659 internal_error (__FILE__, __LINE__, 02660 _("Invalid register %d in cygwin_set_dr.\n"), i); 02661 dr[i] = addr; 02662 debug_registers_changed = 1; 02663 debug_registers_used = 1; 02664 } 02665 02666 /* Pass the value VAL to the inferior in the DR7 debug control 02667 register. Here we just store the address in D_REGS, the watchpoint 02668 will be actually set up in windows_wait. */ 02669 static void 02670 cygwin_set_dr7 (unsigned long val) 02671 { 02672 dr[7] = (CORE_ADDR) val; 02673 debug_registers_changed = 1; 02674 debug_registers_used = 1; 02675 } 02676 02677 /* Get the value of debug register I from the inferior. */ 02678 02679 static CORE_ADDR 02680 cygwin_get_dr (int i) 02681 { 02682 return dr[i]; 02683 } 02684 02685 /* Get the value of the DR6 debug status register from the inferior. 02686 Here we just return the value stored in dr[6] 02687 by the last call to thread_rec for current_event.dwThreadId id. */ 02688 static unsigned long 02689 cygwin_get_dr6 (void) 02690 { 02691 return (unsigned long) dr[6]; 02692 } 02693 02694 /* Get the value of the DR7 debug status register from the inferior. 02695 Here we just return the value stored in dr[7] by the last call to 02696 thread_rec for current_event.dwThreadId id. */ 02697 02698 static unsigned long 02699 cygwin_get_dr7 (void) 02700 { 02701 return (unsigned long) dr[7]; 02702 } 02703 02704 /* Determine if the thread referenced by "ptid" is alive 02705 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 02706 it means that the thread has died. Otherwise it is assumed to be alive. */ 02707 static int 02708 windows_thread_alive (struct target_ops *ops, ptid_t ptid) 02709 { 02710 int tid; 02711 02712 gdb_assert (ptid_get_tid (ptid) != 0); 02713 tid = ptid_get_tid (ptid); 02714 02715 return WaitForSingleObject (thread_rec (tid, FALSE)->h, 0) == WAIT_OBJECT_0 02716 ? FALSE : TRUE; 02717 } 02718 02719 /* -Wmissing-prototypes */ 02720 extern initialize_file_ftype _initialize_check_for_gdb_ini; 02721 02722 void 02723 _initialize_check_for_gdb_ini (void) 02724 { 02725 char *homedir; 02726 if (inhibit_gdbinit) 02727 return; 02728 02729 homedir = getenv ("HOME"); 02730 if (homedir) 02731 { 02732 char *p; 02733 char *oldini = (char *) alloca (strlen (homedir) + 02734 sizeof ("/gdb.ini")); 02735 strcpy (oldini, homedir); 02736 p = strchr (oldini, '\0'); 02737 if (p > oldini && !IS_DIR_SEPARATOR (p[-1])) 02738 *p++ = '/'; 02739 strcpy (p, "gdb.ini"); 02740 if (access (oldini, 0) == 0) 02741 { 02742 int len = strlen (oldini); 02743 char *newini = alloca (len + 1); 02744 02745 xsnprintf (newini, len + 1, "%.*s.gdbinit", 02746 (int) (len - (sizeof ("gdb.ini") - 1)), oldini); 02747 warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini); 02748 } 02749 } 02750 } 02751 02752 /* Define dummy functions which always return error for the rare cases where 02753 these functions could not be found. */ 02754 static BOOL WINAPI 02755 bad_DebugActiveProcessStop (DWORD w) 02756 { 02757 return FALSE; 02758 } 02759 static BOOL WINAPI 02760 bad_DebugBreakProcess (HANDLE w) 02761 { 02762 return FALSE; 02763 } 02764 static BOOL WINAPI 02765 bad_DebugSetProcessKillOnExit (BOOL w) 02766 { 02767 return FALSE; 02768 } 02769 static BOOL WINAPI 02770 bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z) 02771 { 02772 return FALSE; 02773 } 02774 02775 #ifdef __USEWIDE 02776 static DWORD WINAPI 02777 bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z) 02778 { 02779 return 0; 02780 } 02781 #else 02782 static DWORD WINAPI 02783 bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z) 02784 { 02785 return 0; 02786 } 02787 #endif 02788 02789 static BOOL WINAPI 02790 bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z) 02791 { 02792 return FALSE; 02793 } 02794 02795 static BOOL WINAPI 02796 bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y) 02797 { 02798 return FALSE; 02799 } 02800 02801 static BOOL WINAPI 02802 bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f) 02803 { 02804 f->nFont = 0; 02805 return 1; 02806 } 02807 static COORD WINAPI 02808 bad_GetConsoleFontSize (HANDLE w, DWORD nFont) 02809 { 02810 COORD size; 02811 size.X = 8; 02812 size.Y = 12; 02813 return size; 02814 } 02815 02816 /* -Wmissing-prototypes */ 02817 extern initialize_file_ftype _initialize_loadable; 02818 02819 /* Load any functions which may not be available in ancient versions 02820 of Windows. */ 02821 02822 void 02823 _initialize_loadable (void) 02824 { 02825 HMODULE hm = NULL; 02826 02827 hm = LoadLibrary ("kernel32.dll"); 02828 if (hm) 02829 { 02830 DebugActiveProcessStop = (void *) 02831 GetProcAddress (hm, "DebugActiveProcessStop"); 02832 DebugBreakProcess = (void *) 02833 GetProcAddress (hm, "DebugBreakProcess"); 02834 DebugSetProcessKillOnExit = (void *) 02835 GetProcAddress (hm, "DebugSetProcessKillOnExit"); 02836 GetConsoleFontSize = (void *) 02837 GetProcAddress (hm, "GetConsoleFontSize"); 02838 GetCurrentConsoleFont = (void *) 02839 GetProcAddress (hm, "GetCurrentConsoleFont"); 02840 } 02841 02842 /* Set variables to dummy versions of these processes if the function 02843 wasn't found in kernel32.dll. */ 02844 if (!DebugBreakProcess) 02845 DebugBreakProcess = bad_DebugBreakProcess; 02846 if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit) 02847 { 02848 DebugActiveProcessStop = bad_DebugActiveProcessStop; 02849 DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit; 02850 } 02851 if (!GetConsoleFontSize) 02852 GetConsoleFontSize = bad_GetConsoleFontSize; 02853 if (!GetCurrentConsoleFont) 02854 GetCurrentConsoleFont = bad_GetCurrentConsoleFont; 02855 02856 /* Load optional functions used for retrieving filename information 02857 associated with the currently debugged process or its dlls. */ 02858 hm = LoadLibrary ("psapi.dll"); 02859 if (hm) 02860 { 02861 EnumProcessModules = (void *) 02862 GetProcAddress (hm, "EnumProcessModules"); 02863 GetModuleInformation = (void *) 02864 GetProcAddress (hm, "GetModuleInformation"); 02865 GetModuleFileNameEx = (void *) 02866 GetProcAddress (hm, GetModuleFileNameEx_name); 02867 } 02868 02869 if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx) 02870 { 02871 /* Set variables to dummy versions of these processes if the function 02872 wasn't found in psapi.dll. */ 02873 EnumProcessModules = bad_EnumProcessModules; 02874 GetModuleInformation = bad_GetModuleInformation; 02875 GetModuleFileNameEx = bad_GetModuleFileNameEx; 02876 /* This will probably fail on Windows 9x/Me. Let the user know 02877 that we're missing some functionality. */ 02878 warning(_("\ 02879 cannot automatically find executable file or library to read symbols.\n\ 02880 Use \"file\" or \"dll\" command to load executable/libraries directly.")); 02881 } 02882 02883 hm = LoadLibrary ("advapi32.dll"); 02884 if (hm) 02885 { 02886 OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken"); 02887 LookupPrivilegeValueA = (void *) 02888 GetProcAddress (hm, "LookupPrivilegeValueA"); 02889 AdjustTokenPrivileges = (void *) 02890 GetProcAddress (hm, "AdjustTokenPrivileges"); 02891 /* Only need to set one of these since if OpenProcessToken fails nothing 02892 else is needed. */ 02893 if (!OpenProcessToken || !LookupPrivilegeValueA 02894 || !AdjustTokenPrivileges) 02895 OpenProcessToken = bad_OpenProcessToken; 02896 } 02897 }