X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fwindows-nat.c;h=42a6046a48714a4e1991a8fc42d40c74afc6acc8;hb=ece957c859c00fbea7152a2275674d7061dc468a;hp=fe40c4db142a0bd59f3f365138de7ee7ab142982;hpb=d6b6434614d9752d705d4f3199c3d59330938c66;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index fe40c4db14..42a6046a48 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -1,6 +1,6 @@ /* Target-vector operations for controlling windows child processes, for GDB. - Copyright (C) 1995-2014 Free Software Foundation, Inc. + Copyright (C) 1995-2015 Free Software Foundation, Inc. Contributed by Cygnus Solutions, A Red Hat Company. @@ -24,8 +24,8 @@ #include "defs.h" #include "frame.h" /* required by inferior.h */ #include "inferior.h" +#include "infrun.h" #include "target.h" -#include "exceptions.h" #include "gdbcore.h" #include "command.h" #include "completer.h" @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,6 @@ #include "objfiles.h" #include "gdb_bfd.h" #include "gdb_obstack.h" -#include #include "gdbthread.h" #include "gdbcmd.h" #include @@ -64,7 +62,7 @@ #include "windows-tdep.h" #include "windows-nat.h" -#include "i386-nat.h" +#include "x86-nat.h" #include "complaints.h" #include "inf-child.h" @@ -132,7 +130,6 @@ static CONTEXT saved_context; /* Containes the saved context from a enum { FLAG_TRACE_BIT = 0x100, - CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT) }; #endif @@ -142,8 +139,9 @@ enum #define CONTEXT_EXTENDED_REGISTERS 0 #endif -#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \ - | CONTEXT_EXTENDED_REGISTERS +#define CONTEXT_DEBUGGER_DR CONTEXT_FULL | CONTEXT_FLOATING_POINT \ + | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \ + | CONTEXT_EXTENDED_REGISTERS static uintptr_t dr[8]; static int debug_registers_changed; @@ -309,12 +307,18 @@ thread_rec (DWORD id, int get_context) { DWORD err = GetLastError (); - warning (_("SuspendThread (tid=0x%x) failed." - " (winerr %u)"), - (unsigned) id, (unsigned) err); - return NULL; + /* We get Access Denied (5) when trying to suspend + threads that Windows started on behalf of the + debuggee, usually when those threads are just + about to exit. */ + if (err != ERROR_ACCESS_DENIED) + warning (_("SuspendThread (tid=0x%x) failed." + " (winerr %u)"), + (unsigned) id, (unsigned) err); + th->suspended = -1; } - th->suspended = 1; + else + th->suspended = 1; } else if (get_context < 0) th->suspended = -1; @@ -444,7 +448,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) { thread_info *th = current_thread; th->context.ContextFlags = CONTEXT_DEBUGGER_DR; - GetThreadContext (th->h, &th->context); + CHECK (GetThreadContext (th->h, &th->context)); /* Copy dr values from that thread. But only if there were not modified since last stop. PR gdb/2388 */ @@ -547,61 +551,6 @@ struct lm_info static struct so_list solib_start, *solib_end; -/* Call symbol_file_add with stderr redirected. We don't care if there - are errors. */ -static int -safe_symbol_file_add_stub (void *argv) -{ -#define p ((struct safe_symbol_file_add_args *) argv) - const int add_flags = ((p->from_tty ? SYMFILE_VERBOSE : 0) - | (p->mainline ? SYMFILE_MAINLINE : 0)); - p->ret = symbol_file_add (p->name, add_flags, p->addrs, p->flags); - return !!p->ret; -#undef p -} - -/* Restore gdb's stderr after calling symbol_file_add. */ -static void -safe_symbol_file_add_cleanup (void *p) -{ -#define sp ((struct safe_symbol_file_add_args *)p) - gdb_flush (gdb_stderr); - gdb_flush (gdb_stdout); - ui_file_delete (gdb_stderr); - ui_file_delete (gdb_stdout); - gdb_stderr = sp->err; - gdb_stdout = sp->out; -#undef sp -} - -/* symbol_file_add wrapper that prevents errors from being displayed. */ -static struct objfile * -safe_symbol_file_add (char *name, int from_tty, - struct section_addr_info *addrs, - int mainline, int flags) -{ - struct safe_symbol_file_add_args p; - struct cleanup *cleanup; - - cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p); - - p.err = gdb_stderr; - p.out = gdb_stdout; - gdb_flush (gdb_stderr); - gdb_flush (gdb_stdout); - gdb_stderr = ui_file_new (); - gdb_stdout = ui_file_new (); - p.name = name; - p.from_tty = from_tty; - p.addrs = addrs; - p.mainline = mainline; - p.flags = flags; - catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR); - - do_cleanups (cleanup); - return p.ret; -} - static struct so_list * windows_make_so (const char *name, LPVOID load_addr) { @@ -850,28 +799,6 @@ windows_clear_solib (void) solib_end = &solib_start; } -/* Load DLL symbol info. */ -static void -dll_symbol_command (char *args, int from_tty) -{ - int n; - dont_repeat (); - - if (args == NULL) - error (_("dll-symbols requires a file name")); - - n = strlen (args); - if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0) - { - char *newargs = (char *) alloca (n + 4 + 1); - strcpy (newargs, args); - strcat (newargs, ".dll"); - args = newargs; - } - - safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED); -} - /* Handle DEBUG_STRING output from child process. Cygwin prepends its messages with a "cygwin:". Interpret this as a Cygwin signal. Otherwise just print the string as a warning. */ @@ -886,11 +813,10 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) &s, 1024, 0) || !s || !*s) /* nothing to do */; - else if (strncmp (s, _CYGWIN_SIGNAL_STRING, - sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0) + else if (!startswith (s, _CYGWIN_SIGNAL_STRING)) { #ifdef __CYGWIN__ - if (strncmp (s, "cYg", 3) != 0) + if (!startswith (s, "cYg")) #endif warning (("%s"), s); } @@ -1087,8 +1013,7 @@ handle_exception (struct target_waitstatus *ourstatus) if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end)) || (find_pc_partial_function (addr, &fn, NULL, NULL) - && strncmp (fn, "KERNEL32!IsBad", - strlen ("KERNEL32!IsBad")) == 0)) + && startswith (fn, "KERNEL32!IsBad"))) return 0; } #endif @@ -1181,10 +1106,12 @@ handle_exception (struct target_waitstatus *ourstatus) return 1; } -/* Resume all artificially suspended threads if we are continuing - execution. */ +/* Resume thread specified by ID, or all artificially suspended + threads, if we are continuing execution. KILLED non-zero means we + have killed the inferior, so we should ignore weird errors due to + threads shutting down. */ static BOOL -windows_continue (DWORD continue_status, int id) +windows_continue (DWORD continue_status, int id, int killed) { int i; thread_info *th; @@ -1212,7 +1139,16 @@ windows_continue (DWORD continue_status, int id) } if (th->context.ContextFlags) { - CHECK (SetThreadContext (th->h, &th->context)); + DWORD ec = 0; + + if (GetExitCodeThread (th->h, &ec) + && ec == STILL_ACTIVE) + { + BOOL status = SetThreadContext (th->h, &th->context); + + if (!killed) + CHECK (status); + } th->context.ContextFlags = 0; } if (th->suspended > 0) @@ -1340,9 +1276,9 @@ windows_resume (struct target_ops *ops, Otherwise complain. */ if (resume_all) - windows_continue (continue_status, -1); + windows_continue (continue_status, -1, 0); else - windows_continue (continue_status, ptid_get_tid (ptid)); + windows_continue (continue_status, ptid_get_tid (ptid), 0); } /* Ctrl-C handler used when the inferior is not run in the same console. The @@ -1560,7 +1496,7 @@ get_windows_debug_event (struct target_ops *ops, if (continue_status == -1) windows_resume (ops, minus_one_ptid, 0, 1); else - CHECK (windows_continue (continue_status, -1)); + CHECK (windows_continue (continue_status, -1, 0)); } else { @@ -1709,10 +1645,11 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) #endif current_event.dwProcessId = pid; memset (¤t_event, 0, sizeof (current_event)); - push_target (ops); + if (!target_is_pushed (ops)) + push_target (ops); disable_breakpoints_in_shlibs (); windows_clear_solib (); - clear_proceed_status (); + clear_proceed_status (0); init_wait_for_inferior (); inf = current_inferior (); @@ -1725,7 +1662,7 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) current thread until we report an event out of windows_wait. */ inferior_ptid = pid_to_ptid (pid); - child_terminal_init_with_pgrp (pid); + target_terminal_init (); target_terminal_inferior (); windows_initialization_done = 0; @@ -1815,7 +1752,7 @@ out: /* Attach to process PID, then initialize for debugging it. */ static void -windows_attach (struct target_ops *ops, char *args, int from_tty) +windows_attach (struct target_ops *ops, const char *args, int from_tty) { BOOL ok; DWORD pid; @@ -1893,11 +1830,11 @@ windows_detach (struct target_ops *ops, const char *args, int from_tty) gdb_flush (gdb_stdout); } - i386_cleanup_dregs (); + x86_cleanup_dregs (); inferior_ptid = null_ptid; detach_inferior (current_event.dwProcessId); - unpush_target (ops); + inf_child_maybe_unpush_target (ops); } /* Try to determine the executable filename. @@ -2337,21 +2274,20 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, do_initial_windows_stuff (ops, pi.dwProcessId, 0); - /* windows_continue (DBG_CONTINUE, -1); */ + /* windows_continue (DBG_CONTINUE, -1, 0); */ } static void windows_mourn_inferior (struct target_ops *ops) { - (void) windows_continue (DBG_CONTINUE, -1); - i386_cleanup_dregs(); + (void) windows_continue (DBG_CONTINUE, -1, 0); + x86_cleanup_dregs(); if (open_process_used) { CHECK (CloseHandle (current_process_handle)); open_process_used = 0; } - unpush_target (ops); - generic_mourn_inferior (); + inf_child_mourn_inferior (ops); } /* Send a SIGINT to the process group. This acts just like the user typed a @@ -2412,7 +2348,7 @@ windows_kill_inferior (struct target_ops *ops) for (;;) { - if (!windows_continue (DBG_CONTINUE, -1)) + if (!windows_continue (DBG_CONTINUE, -1, 1)) break; if (!WaitForDebugEvent (¤t_event, INFINITE)) break; @@ -2501,11 +2437,9 @@ windows_xfer_partial (struct target_ops *ops, enum target_object object, writebuf, offset, len, xfered_len); default: - if (ops->beneath != NULL) - return ops->beneath->to_xfer_partial (ops->beneath, object, annex, - readbuf, writebuf, offset, len, - xfered_len); - return TARGET_XFER_E_IO; + return ops->beneath->to_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len, + xfered_len); } } @@ -2539,9 +2473,6 @@ windows_target (void) { struct target_ops *t = inf_child_target (); - t->to_shortname = "child"; - t->to_longname = "Win32 child process"; - t->to_doc = "Win32 child process (started by the \"run\" command)."; t->to_close = windows_close; t->to_attach = windows_attach; t->to_attach_no_wait = 1; @@ -2577,21 +2508,20 @@ extern initialize_file_ftype _initialize_windows_nat; void _initialize_windows_nat (void) { - struct cmd_list_element *c; struct target_ops *t; t = windows_target (); - i386_use_watchpoints (t); + x86_use_watchpoints (t); - i386_dr_low.set_control = cygwin_set_dr7; - i386_dr_low.set_addr = cygwin_set_dr; - i386_dr_low.get_addr = cygwin_get_dr; - i386_dr_low.get_status = cygwin_get_dr6; - i386_dr_low.get_control = cygwin_get_dr7; + x86_dr_low.set_control = cygwin_set_dr7; + x86_dr_low.set_addr = cygwin_set_dr; + x86_dr_low.get_addr = cygwin_get_dr; + x86_dr_low.get_status = cygwin_get_dr6; + x86_dr_low.get_control = cygwin_get_dr7; - /* i386_dr_low.debug_register_length field is set by - calling i386_set_debug_register_length function + /* x86_dr_low.debug_register_length field is set by + calling x86_set_debug_register_length function in processor windows specific native file. */ add_target (t); @@ -2600,21 +2530,6 @@ _initialize_windows_nat (void) cygwin_internal (CW_SET_DOS_FILE_WARNING, 0); #endif - c = add_com ("dll-symbols", class_files, dll_symbol_command, - _("Load dll library symbols from FILE.")); - set_cmd_completer (c, filename_completer); - deprecate_cmd (c, "sharedlibrary"); - - c = add_com ("add-shared-symbol-files", class_files, dll_symbol_command, - _("Load dll library symbols from FILE.")); - set_cmd_completer (c, filename_completer); - deprecate_cmd (c, "sharedlibrary"); - - c = add_com ("assf", class_files, dll_symbol_command, - _("Load dll library symbols from FILE.")); - set_cmd_completer (c, filename_completer); - deprecate_cmd (c, "sharedlibrary"); - #ifdef __CYGWIN__ add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\ Set use of shell to start subprocess."), _("\