X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fwindows-nat.c;h=c6a809b0b2f54ace8d39dd5859c721ace0aaf772;hb=9eee20eb5400345cab1952cbfc0426035ddf1140;hp=5dcd520fbabe62a0ba39531aa82bd3fe9aea0691;hpb=d7096f716534f280fba72a5b2ec3712ad1aea42e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 5dcd520fba..c6a809b0b2 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-2016 Free Software Foundation, Inc. Contributed by Cygnus Solutions, A Red Hat Company. @@ -26,7 +26,6 @@ #include "inferior.h" #include "infrun.h" #include "target.h" -#include "exceptions.h" #include "gdbcore.h" #include "command.h" #include "completer.h" @@ -50,7 +49,6 @@ #include "objfiles.h" #include "gdb_bfd.h" #include "gdb_obstack.h" -#include #include "gdbthread.h" #include "gdbcmd.h" #include @@ -58,13 +56,14 @@ #include "solist.h" #include "solib.h" #include "xml-support.h" +#include "inttypes.h" #include "i386-tdep.h" #include "i387-tdep.h" #include "windows-tdep.h" #include "windows-nat.h" -#include "i386-nat.h" +#include "x86-nat.h" #include "complaints.h" #include "inf-child.h" @@ -79,20 +78,41 @@ #define GetConsoleFontSize dyn_GetConsoleFontSize #define GetCurrentConsoleFont dyn_GetCurrentConsoleFont -static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, - DWORD, PTOKEN_PRIVILEGES, PDWORD); -static BOOL WINAPI (*DebugActiveProcessStop) (DWORD); -static BOOL WINAPI (*DebugBreakProcess) (HANDLE); -static BOOL WINAPI (*DebugSetProcessKillOnExit) (BOOL); -static BOOL WINAPI (*EnumProcessModules) (HANDLE, HMODULE *, DWORD, - LPDWORD); -static BOOL WINAPI (*GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, - DWORD); -static BOOL WINAPI (*LookupPrivilegeValueA)(LPCSTR, LPCSTR, PLUID); -static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE); -static BOOL WINAPI (*GetCurrentConsoleFont) (HANDLE, BOOL, - CONSOLE_FONT_INFO *); -static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); +typedef BOOL WINAPI (AdjustTokenPrivileges_ftype) (HANDLE, BOOL, + PTOKEN_PRIVILEGES, + DWORD, PTOKEN_PRIVILEGES, + PDWORD); +static AdjustTokenPrivileges_ftype *AdjustTokenPrivileges; + +typedef BOOL WINAPI (DebugActiveProcessStop_ftype) (DWORD); +static DebugActiveProcessStop_ftype *DebugActiveProcessStop; + +typedef BOOL WINAPI (DebugBreakProcess_ftype) (HANDLE); +static DebugBreakProcess_ftype *DebugBreakProcess; + +typedef BOOL WINAPI (DebugSetProcessKillOnExit_ftype) (BOOL); +static DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit; + +typedef BOOL WINAPI (EnumProcessModules_ftype) (HANDLE, HMODULE *, DWORD, + LPDWORD); +static EnumProcessModules_ftype *EnumProcessModules; + +typedef BOOL WINAPI (GetModuleInformation_ftype) (HANDLE, HMODULE, + LPMODULEINFO, DWORD); +static GetModuleInformation_ftype *GetModuleInformation; + +typedef BOOL WINAPI (LookupPrivilegeValueA_ftype) (LPCSTR, LPCSTR, PLUID); +static LookupPrivilegeValueA_ftype *LookupPrivilegeValueA; + +typedef BOOL WINAPI (OpenProcessToken_ftype) (HANDLE, DWORD, PHANDLE); +static OpenProcessToken_ftype *OpenProcessToken; + +typedef BOOL WINAPI (GetCurrentConsoleFont_ftype) (HANDLE, BOOL, + CONSOLE_FONT_INFO *); +static GetCurrentConsoleFont_ftype *GetCurrentConsoleFont; + +typedef COORD WINAPI (GetConsoleFontSize_ftype) (HANDLE, DWORD); +static GetConsoleFontSize_ftype *GetConsoleFontSize; #undef STARTUPINFO #undef CreateProcess @@ -100,7 +120,8 @@ static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); #ifndef __CYGWIN__ # define __PMAX (MAX_PATH + 1) - static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, LPSTR, DWORD); + typedef DWORD WINAPI (GetModuleFileNameEx_ftype) (HANDLE, HMODULE, LPSTR, DWORD); + static GetModuleFileNameEx_ftype *GetModuleFileNameEx; # define STARTUPINFO STARTUPINFOA # define CreateProcess CreateProcessA # define GetModuleFileNameEx_name "GetModuleFileNameExA" @@ -112,8 +133,9 @@ static COORD WINAPI (*GetConsoleFontSize) (HANDLE, DWORD); static CORE_ADDR cygwin_load_end; # define __USEWIDE typedef wchar_t cygwin_buf_t; - static DWORD WINAPI (*GetModuleFileNameEx) (HANDLE, HMODULE, - LPWSTR, DWORD); + typedef DWORD WINAPI (GetModuleFileNameEx_ftype) (HANDLE, HMODULE, + LPWSTR, DWORD); + static GetModuleFileNameEx_ftype *GetModuleFileNameEx; # define STARTUPINFO STARTUPINFOW # define CreateProcess CreateProcessW # define GetModuleFileNameEx_name "GetModuleFileNameExW" @@ -132,7 +154,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 +163,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; @@ -152,6 +174,19 @@ static int debug_registers_used; static int windows_initialization_done; #define DR6_CLEAR_VALUE 0xffff0ff0 +/* The exception thrown by a program to tell the debugger the name of + a thread. The exception record contains an ID of a thread and a + name to give it. This exception has no documented name, but MSDN + dubs it "MS_VC_EXCEPTION" in one code example. */ +#define MS_VC_EXCEPTION 0x406d1388 + +typedef enum +{ + HANDLE_EXCEPTION_UNHANDLED = 0, + HANDLE_EXCEPTION_HANDLED, + HANDLE_EXCEPTION_IGNORED +} handle_exception_result; + /* The string sent by cygwin when it processes a signal. FIXME: This should be in a cygwin include file. */ #ifndef _CYGWIN_SIGNAL_STRING @@ -164,7 +199,7 @@ static int windows_initialization_done; #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x -static void windows_stop (struct target_ops *self, ptid_t); +static void windows_interrupt (struct target_ops *self, ptid_t); static int windows_thread_alive (struct target_ops *, ptid_t); static void windows_kill_inferior (struct target_ops *); @@ -179,9 +214,9 @@ static enum gdb_signal last_sig = GDB_SIGNAL_0; /* Thread information structure used to track information that is not available in gdb's thread structure. */ -typedef struct thread_info_struct +typedef struct windows_thread_info_struct { - struct thread_info_struct *next; + struct windows_thread_info_struct *next; DWORD id; HANDLE h; CORE_ADDR thread_local_base; @@ -191,16 +226,16 @@ typedef struct thread_info_struct CONTEXT context; STACKFRAME sf; } -thread_info; +windows_thread_info; -static thread_info thread_head; +static windows_thread_info thread_head; /* The process and thread handles for the above context. */ static DEBUG_EVENT current_event; /* The current debug event from WaitForDebugEvent */ static HANDLE current_process_handle; /* Currently executing process */ -static thread_info *current_thread; /* Info on currently selected thread */ +static windows_thread_info *current_thread; /* Info on currently selected thread */ static DWORD main_thread_id; /* Thread ID of the main thread */ /* Counts of things. */ @@ -263,7 +298,7 @@ static const struct xlate_exception {DBG_CONTROL_C, GDB_SIGNAL_INT}, {EXCEPTION_SINGLE_STEP, GDB_SIGNAL_TRAP}, {STATUS_FLOAT_DIVIDE_BY_ZERO, GDB_SIGNAL_FPE}, - {-1, -1}}; + {-1, GDB_SIGNAL_UNKNOWN}}; /* Set the MAPPINGS static global to OFFSETS. See the description of MAPPINGS for more details. */ @@ -293,10 +328,10 @@ check (BOOL ok, const char *file, int line) /* Find a thread record given a thread id. If GET_CONTEXT is not 0, then also retrieve the context for this thread. If GET_CONTEXT is negative, then don't suspend the thread. */ -static thread_info * +static windows_thread_info * thread_rec (DWORD id, int get_context) { - thread_info *th; + windows_thread_info *th; for (th = &thread_head; (th = th->next) != NULL;) if (th->id == id) @@ -312,8 +347,11 @@ thread_rec (DWORD id, int get_context) /* 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) + about to exit. + We can get Invalid Handle (6) if the main thread + has exited. */ + if (err != ERROR_INVALID_HANDLE + && err != ERROR_ACCESS_DENIED) warning (_("SuspendThread (tid=0x%x) failed." " (winerr %u)"), (unsigned) id, (unsigned) err); @@ -333,10 +371,10 @@ thread_rec (DWORD id, int get_context) } /* Add a thread to the thread list. */ -static thread_info * +static windows_thread_info * windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) { - thread_info *th; + windows_thread_info *th; DWORD id; gdb_assert (ptid_get_tid (ptid) != 0); @@ -346,7 +384,7 @@ windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) if ((th = thread_rec (id, FALSE))) return th; - th = XCNEW (thread_info); + th = XCNEW (windows_thread_info); th->id = id; th->h = h; th->thread_local_base = (CORE_ADDR) (uintptr_t) tlb; @@ -376,13 +414,13 @@ windows_add_thread (ptid_t ptid, HANDLE h, void *tlb) static void windows_init_thread_list (void) { - thread_info *th = &thread_head; + windows_thread_info *th = &thread_head; DEBUG_EVENTS (("gdb: windows_init_thread_list\n")); init_thread_list (); while (th->next != NULL) { - thread_info *here = th->next; + windows_thread_info *here = th->next; th->next = here->next; xfree (here); } @@ -393,7 +431,7 @@ windows_init_thread_list (void) static void windows_delete_thread (ptid_t ptid, DWORD exit_code) { - thread_info *th; + windows_thread_info *th; DWORD id; gdb_assert (ptid_get_tid (ptid) != 0); @@ -414,8 +452,9 @@ windows_delete_thread (ptid_t ptid, DWORD exit_code) if (th->next != NULL) { - thread_info *here = th->next; + windows_thread_info *here = th->next; th->next = here->next; + xfree (here->name); xfree (here); } } @@ -434,7 +473,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) if (current_thread->reload_context) { -#ifdef __COPY_CONTEXT_SIZE +#ifdef __CYGWIN__ if (have_saved_context) { /* Lie about where the program actually is stopped since @@ -448,7 +487,7 @@ do_windows_fetch_inferior_registers (struct regcache *regcache, int r) else #endif { - thread_info *th = current_thread; + windows_thread_info *th = current_thread; th->context.ContextFlags = CONTEXT_DEBUGGER_DR; CHECK (GetThreadContext (th->h, &th->context)); /* Copy dr values from that thread. @@ -553,61 +592,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) { @@ -661,7 +645,7 @@ windows_make_so (const char *name, LPVOID load_addr) } #endif so = XCNEW (struct so_list); - so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); + so->lm_info = XNEW (struct lm_info); so->lm_info->load_addr = load_addr; strcpy (so->so_original_name, name); #ifndef __CYGWIN__ @@ -856,26 +840,23 @@ windows_clear_solib (void) solib_end = &solib_start; } -/* Load DLL symbol info. */ static void -dll_symbol_command (char *args, int from_tty) +signal_event_command (char *args, int from_tty) { - int n; - dont_repeat (); + uintptr_t event_id = 0; + char *endargs = NULL; if (args == NULL) - error (_("dll-symbols requires a file name")); + error (_("signal-event requires an argument (integer event id)")); - 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; - } + event_id = strtoumax (args, &endargs, 10); - safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED); + if ((errno == ERANGE) || (event_id == 0) || (event_id > UINTPTR_MAX) || + ((HANDLE) event_id == INVALID_HANDLE_VALUE)) + error (_("Failed to convert `%s' to event id"), args); + + SetEvent ((HANDLE) event_id); + CloseHandle ((HANDLE) event_id); } /* Handle DEBUG_STRING output from child process. @@ -892,15 +873,20 @@ 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); + { + char *p = strchr (s, '\0'); + + if (p > s && *--p == '\n') + *p = '\0'; + warning (("%s"), s); + } } -#ifdef __COPY_CONTEXT_SIZE +#ifdef __CYGWIN__ else { /* Got a cygwin signal marker. A cygwin signal is followed by @@ -912,7 +898,7 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) to treat this like a real signal. */ char *p; int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0); - int gotasig = gdb_signal_from_host (sig); + gdb_signal gotasig = gdb_signal_from_host (sig); ourstatus->value.sig = gotasig; if (gotasig) @@ -930,7 +916,6 @@ handle_output_debug_string (struct target_waitstatus *ourstatus) __COPY_CONTEXT_SIZE, &n) && n == __COPY_CONTEXT_SIZE) have_saved_context = 1; - current_event.dwThreadId = retval; } } #endif @@ -1060,16 +1045,17 @@ display_selectors (char * args, int from_tty) host_address_to_string (\ current_event.u.Exception.ExceptionRecord.ExceptionAddress)) -static int +static handle_exception_result handle_exception (struct target_waitstatus *ourstatus) { - thread_info *th; - DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode; + EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord; + DWORD code = rec->ExceptionCode; + handle_exception_result result = HANDLE_EXCEPTION_HANDLED; ourstatus->kind = TARGET_WAITKIND_STOPPED; /* Record the context of the current thread. */ - th = thread_rec (current_event.dwThreadId, -1); + thread_rec (current_event.dwThreadId, -1); switch (code) { @@ -1087,15 +1073,13 @@ handle_exception (struct target_waitstatus *ourstatus) cygwin-specific-signal. So, ignore SEGVs if they show up within the text segment of the DLL itself. */ const char *fn; - CORE_ADDR addr = (CORE_ADDR) (uintptr_t) - current_event.u.Exception.ExceptionRecord.ExceptionAddress; + CORE_ADDR addr = (CORE_ADDR) (uintptr_t) rec->ExceptionAddress; 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)) - return 0; + && startswith (fn, "KERNEL32!IsBad"))) + return HANDLE_EXCEPTION_UNHANDLED; } #endif break; @@ -1171,10 +1155,48 @@ handle_exception (struct target_waitstatus *ourstatus) DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION"); ourstatus->value.sig = GDB_SIGNAL_ILL; break; + case MS_VC_EXCEPTION: + if (rec->NumberParameters >= 3 + && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000) + { + DWORD named_thread_id; + windows_thread_info *named_thread; + CORE_ADDR thread_name_target; + + DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION"); + + thread_name_target = rec->ExceptionInformation[1]; + named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]); + + if (named_thread_id == (DWORD) -1) + named_thread_id = current_event.dwThreadId; + + named_thread = thread_rec (named_thread_id, 0); + if (named_thread != NULL) + { + int thread_name_len; + char *thread_name; + + thread_name_len = target_read_string (thread_name_target, + &thread_name, 1025, NULL); + if (thread_name_len > 0) + { + thread_name[thread_name_len - 1] = '\0'; + xfree (named_thread->name); + named_thread->name = thread_name; + } + else + xfree (thread_name); + } + ourstatus->value.sig = GDB_SIGNAL_TRAP; + result = HANDLE_EXCEPTION_IGNORED; + break; + } + /* treat improperly formed exception as unknown, fallthrough */ default: /* Treat unhandled first chance exceptions specially. */ if (current_event.u.Exception.dwFirstChance) - return -1; + return HANDLE_EXCEPTION_UNHANDLED; printf_unfiltered ("gdb: unknown target exception 0x%08x at %s\n", (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode, host_address_to_string ( @@ -1184,7 +1206,7 @@ handle_exception (struct target_waitstatus *ourstatus) } exception_count++; last_sig = ourstatus->value.sig; - return 1; + return result; } /* Resume thread specified by ID, or all artificially suspended @@ -1195,7 +1217,7 @@ static BOOL windows_continue (DWORD continue_status, int id, int killed) { int i; - thread_info *th; + windows_thread_info *th; BOOL res; DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n", @@ -1241,6 +1263,11 @@ windows_continue (DWORD continue_status, int id, int killed) current_event.dwThreadId, continue_status); + if (!res) + error (_("Failed to resume program execution" + " (ContinueDebugEvent failed, error %u)"), + (unsigned int) GetLastError ()); + debug_registers_changed = 0; return res; } @@ -1273,7 +1300,7 @@ static void windows_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal sig) { - thread_info *th; + windows_thread_info *th; DWORD continue_status = DBG_CONTINUE; /* A specific PTID means `step only this thread id'. */ @@ -1314,7 +1341,7 @@ windows_resume (struct target_ops *ops, } } #endif - DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n", + DEBUG_EXCEPT(("Can only continue with received signal %d.\n", last_sig)); } @@ -1388,17 +1415,17 @@ ctrl_c_handler (DWORD event_type) return TRUE; } -/* Get the next event from the child. Return 1 if the event requires - handling by WFI (or whatever). */ +/* Get the next event from the child. Returns a non-zero thread id if the event + requires handling by WFI (or whatever). */ static int get_windows_debug_event (struct target_ops *ops, int pid, struct target_waitstatus *ourstatus) { BOOL debug_event; DWORD continue_status, event_code; - thread_info *th; - static thread_info dummy_thread_info; - int retval = 0; + windows_thread_info *th; + static windows_thread_info dummy_thread_info; + DWORD thread_id = 0; last_sig = GDB_SIGNAL_0; @@ -1429,14 +1456,14 @@ get_windows_debug_event (struct target_ops *ops, /* Kludge around a Windows bug where first event is a create thread event. Caused when attached process does not have a main thread. */ - retval = fake_create_process (); - if (retval) + thread_id = fake_create_process (); + if (thread_id) saw_create++; } break; } /* Record the existence of this thread. */ - retval = current_event.dwThreadId; + thread_id = current_event.dwThreadId; th = windows_add_thread (ptid_build (current_event.dwProcessId, 0, current_event.dwThreadId), current_event.u.CreateThread.hThread, @@ -1479,7 +1506,7 @@ get_windows_debug_event (struct target_ops *ops, current_event.dwThreadId), current_event.u.CreateProcessInfo.hThread, current_event.u.CreateProcessInfo.lpThreadLocalBase); - retval = current_event.dwThreadId; + thread_id = current_event.dwThreadId; break; case EXIT_PROCESS_DEBUG_EVENT: @@ -1490,7 +1517,7 @@ get_windows_debug_event (struct target_ops *ops, if (!windows_initialization_done) { target_terminal_ours (); - target_mourn_inferior (); + target_mourn_inferior (inferior_ptid); error (_("During startup program exited with code 0x%x."), (unsigned int) current_event.u.ExitProcess.dwExitCode); } @@ -1498,7 +1525,7 @@ get_windows_debug_event (struct target_ops *ops, { ourstatus->kind = TARGET_WAITKIND_EXITED; ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode; - retval = main_thread_id; + thread_id = main_thread_id; } break; @@ -1513,7 +1540,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - retval = main_thread_id; + thread_id = main_thread_id; break; case UNLOAD_DLL_DEBUG_EVENT: @@ -1526,7 +1553,7 @@ get_windows_debug_event (struct target_ops *ops, catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL); ourstatus->kind = TARGET_WAITKIND_LOADED; ourstatus->value.integer = 0; - retval = main_thread_id; + thread_id = main_thread_id; break; case EXCEPTION_DEBUG_EVENT: @@ -1538,15 +1565,15 @@ get_windows_debug_event (struct target_ops *ops, break; switch (handle_exception (ourstatus)) { - case 0: + case HANDLE_EXCEPTION_UNHANDLED: + default: continue_status = DBG_EXCEPTION_NOT_HANDLED; break; - case 1: - retval = current_event.dwThreadId; + case HANDLE_EXCEPTION_HANDLED: + thread_id = current_event.dwThreadId; break; - case -1: - last_sig = 1; - continue_status = -1; + case HANDLE_EXCEPTION_IGNORED: + continue_status = DBG_CONTINUE; break; } break; @@ -1558,7 +1585,7 @@ get_windows_debug_event (struct target_ops *ops, "OUTPUT_DEBUG_STRING_EVENT")); if (saw_create != 1) break; - retval = handle_output_debug_string (ourstatus); + thread_id = handle_output_debug_string (ourstatus); break; default: @@ -1572,22 +1599,21 @@ get_windows_debug_event (struct target_ops *ops, break; } - if (!retval || saw_create != 1) + if (!thread_id || saw_create != 1) { - if (continue_status == -1) - windows_resume (ops, minus_one_ptid, 0, 1); - else - CHECK (windows_continue (continue_status, -1, 0)); + CHECK (windows_continue (continue_status, -1, 0)); } else { inferior_ptid = ptid_build (current_event.dwProcessId, 0, - retval); - current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE); + thread_id); + current_thread = th; + if (!current_thread) + current_thread = thread_rec (thread_id, TRUE); } out: - return retval; + return thread_id; } /* Wait for interesting events to occur in the target process. */ @@ -1708,7 +1734,6 @@ windows_add_all_dlls (void) static void do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) { - extern int stop_after_trap; int i; struct inferior *inf; struct thread_info *tp; @@ -1743,20 +1768,24 @@ 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; - inf->control.stop_soon = STOP_QUIETLY; + while (1) { - stop_after_trap = 1; - wait_for_inferior (); - tp = inferior_thread (); - if (tp->suspend.stop_signal != GDB_SIGNAL_TRAP) - resume (0, tp->suspend.stop_signal); - else + struct target_waitstatus status; + + windows_wait (ops, minus_one_ptid, &status, 0); + + /* Note windows_wait returns TARGET_WAITKIND_SPURIOUS for thread + events. */ + if (status.kind != TARGET_WAITKIND_LOADED + && status.kind != TARGET_WAITKIND_SPURIOUS) break; + + windows_resume (ops, minus_one_ptid, 0, GDB_SIGNAL_0); } /* Now that the inferior has been started and all DLLs have been mapped, @@ -1777,8 +1806,6 @@ do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching) windows_add_all_dlls (); windows_initialization_done = 1; - inf->control.stop_soon = NO_STOP_QUIETLY; - stop_after_trap = 0; return; } @@ -1911,7 +1938,7 @@ 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); @@ -1948,7 +1975,7 @@ windows_get_exec_module_filename (char *exe_name_ret, size_t exe_name_max_len) /* Cygwin prefers that the path be in /x/y/z format, so extract the filename into a temporary buffer first, and then convert it to POSIX format into the destination buffer. */ - cygwin_buf_t *pathbuf = alloca (exe_name_max_len * sizeof (cygwin_buf_t)); + cygwin_buf_t *pathbuf = (cygwin_buf_t *) alloca (exe_name_max_len * sizeof (cygwin_buf_t)); len = GetModuleFileNameEx (current_process_handle, dh_buf, pathbuf, exe_name_max_len); @@ -2274,7 +2301,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, To avoid ambiguities introduced by spaces in the module name, we quote it. */ args_len = strlen (toexec) + 2 /* quotes */ + strlen (allargs) + 2; - args = alloca (args_len); + args = (char *) alloca (args_len); xsnprintf (args, args_len, "\"%s\" %s", toexec, allargs); flags |= DEBUG_ONLY_THIS_PROCESS; @@ -2314,7 +2341,7 @@ windows_create_inferior (struct target_ops *ops, char *exec_file, /* Windows programs expect the environment block to be sorted. */ qsort (env, i, sizeof (char *), envvar_cmp); - w32env = alloca (envlen + 1); + w32env = (char *) alloca (envlen + 1); /* Copy env strings into new buffer. */ for (temp = w32env, i = 0; env[i] && *env[i]; i++) @@ -2362,7 +2389,7 @@ static void windows_mourn_inferior (struct target_ops *ops) { (void) windows_continue (DBG_CONTINUE, -1, 0); - i386_cleanup_dregs(); + x86_cleanup_dregs(); if (open_process_used) { CHECK (CloseHandle (current_process_handle)); @@ -2375,7 +2402,7 @@ windows_mourn_inferior (struct target_ops *ops) ^C on the controlling terminal. */ static void -windows_stop (struct target_ops *self, ptid_t ptid) +windows_interrupt (struct target_ops *self, ptid_t ptid) { DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); @@ -2437,7 +2464,7 @@ windows_kill_inferior (struct target_ops *ops) break; } - target_mourn_inferior (); /* Or just windows_mourn_inferior? */ + target_mourn_inferior (inferior_ptid); /* Or just windows_mourn_inferior? */ } static void @@ -2486,7 +2513,7 @@ windows_xfer_shared_libraries (struct target_ops *ops, target_gdbarch (), &obstack); obstack_grow_str0 (&obstack, "\n"); - buf = obstack_finish (&obstack); + buf = (const char *) obstack_finish (&obstack); len_avail = strlen (buf); if (offset >= len_avail) len= 0; @@ -2531,7 +2558,7 @@ static int windows_get_tib_address (struct target_ops *self, ptid_t ptid, CORE_ADDR *addr) { - thread_info *th; + windows_thread_info *th; th = thread_rec (ptid_get_tid (ptid), 0); if (th == NULL) @@ -2549,6 +2576,14 @@ windows_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) return ptid_build (ptid_get_pid (inferior_ptid), 0, lwp); } +/* Implementation of the to_thread_name method. */ + +static const char * +windows_thread_name (struct target_ops *self, struct thread_info *thr) +{ + return thread_rec (ptid_get_tid (thr->ptid), 0)->name; +} + static struct target_ops * windows_target (void) { @@ -2569,41 +2604,35 @@ windows_target (void) t->to_mourn_inferior = windows_mourn_inferior; t->to_thread_alive = windows_thread_alive; t->to_pid_to_str = windows_pid_to_str; - t->to_stop = windows_stop; + t->to_interrupt = windows_interrupt; t->to_pid_to_exec_file = windows_pid_to_exec_file; t->to_get_ada_task_ptid = windows_get_ada_task_ptid; t->to_get_tib_address = windows_get_tib_address; + t->to_thread_name = windows_thread_name; return t; } -static void -set_windows_aliases (char *argv0) -{ - add_info_alias ("dll", "sharedlibrary", 1); -} - /* -Wmissing-prototypes */ 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); @@ -2612,20 +2641,12 @@ _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"); + add_com ("signal-event", class_run, signal_event_command, _("\ +Signal a crashed process with event ID, to allow its debugging.\n\ +This command is needed in support of setting up GDB as JIT debugger on \ +MS-Windows. The command should be invoked from the GDB command line using \ +the '-ex' command-line option. The ID of the event that blocks the \ +crashed process will be supplied by the Windows JIT debugging mechanism.")); #ifdef __CYGWIN__ add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\ @@ -2692,7 +2713,6 @@ Show whether to display kernel exceptions in child process."), NULL, add_cmd ("selector", class_info, display_selectors, _("Display selectors infos."), &info_w32_cmdlist); - deprecated_init_ui_hook = set_windows_aliases; } /* Hardware watchpoint support, adapted from go32-nat.c code. */ @@ -2779,7 +2799,7 @@ _initialize_check_for_gdb_ini (void) { char *p; char *oldini = (char *) alloca (strlen (homedir) + - sizeof ("/gdb.ini")); + sizeof ("gdb.ini") + 1); strcpy (oldini, homedir); p = strchr (oldini, '\0'); if (p > oldini && !IS_DIR_SEPARATOR (p[-1])) @@ -2788,9 +2808,9 @@ _initialize_check_for_gdb_ini (void) if (access (oldini, 0) == 0) { int len = strlen (oldini); - char *newini = alloca (len + 1); + char *newini = (char *) alloca (len + 2); - xsnprintf (newini, len + 1, "%.*s.gdbinit", + xsnprintf (newini, len + 2, "%.*s.gdbinit", (int) (len - (sizeof ("gdb.ini") - 1)), oldini); warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini); } @@ -2872,19 +2892,18 @@ _initialize_loadable (void) { HMODULE hm = NULL; +#define GPA(m, func) \ + func = (func ## _ftype *) GetProcAddress (m, #func) + hm = LoadLibrary ("kernel32.dll"); if (hm) { - DebugActiveProcessStop = (void *) - GetProcAddress (hm, "DebugActiveProcessStop"); - DebugBreakProcess = (void *) - GetProcAddress (hm, "DebugBreakProcess"); - DebugSetProcessKillOnExit = (void *) - GetProcAddress (hm, "DebugSetProcessKillOnExit"); - GetConsoleFontSize = (void *) - GetProcAddress (hm, "GetConsoleFontSize"); - GetCurrentConsoleFont = (void *) - GetProcAddress (hm, "GetCurrentConsoleFont"); + GPA (hm, DebugActiveProcessStop); + GPA (hm, DebugBreakProcess); + GPA (hm, DebugSetProcessKillOnExit); + GPA (hm, GetConsoleFontSize); + GPA (hm, DebugActiveProcessStop); + GPA (hm, GetCurrentConsoleFont); } /* Set variables to dummy versions of these processes if the function @@ -2906,12 +2925,10 @@ _initialize_loadable (void) hm = LoadLibrary ("psapi.dll"); if (hm) { - EnumProcessModules = (void *) - GetProcAddress (hm, "EnumProcessModules"); - GetModuleInformation = (void *) - GetProcAddress (hm, "GetModuleInformation"); - GetModuleFileNameEx = (void *) - GetProcAddress (hm, GetModuleFileNameEx_name); + GPA (hm, EnumProcessModules); + GPA (hm, GetModuleInformation); + GetModuleFileNameEx = (GetModuleFileNameEx_ftype *) + GetProcAddress (hm, GetModuleFileNameEx_name); } if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx) @@ -2931,15 +2948,15 @@ Use \"file\" or \"dll\" command to load executable/libraries directly.")); hm = LoadLibrary ("advapi32.dll"); if (hm) { - OpenProcessToken = (void *) GetProcAddress (hm, "OpenProcessToken"); - LookupPrivilegeValueA = (void *) - GetProcAddress (hm, "LookupPrivilegeValueA"); - AdjustTokenPrivileges = (void *) - GetProcAddress (hm, "AdjustTokenPrivileges"); + GPA (hm, OpenProcessToken); + GPA (hm, LookupPrivilegeValueA); + GPA (hm, AdjustTokenPrivileges); /* Only need to set one of these since if OpenProcessToken fails nothing else is needed. */ if (!OpenProcessToken || !LookupPrivilegeValueA || !AdjustTokenPrivileges) OpenProcessToken = bad_OpenProcessToken; } + +#undef GPA }