/* Target-vector operations for controlling windows child processes, for GDB.
- Copyright (C) 1995-2020 Free Software Foundation, Inc.
+ Copyright (C) 1995-2022 Free Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
#include <fcntl.h>
#include <windows.h>
#include <imagehlp.h>
-#include <psapi.h>
#ifdef __CYGWIN__
#include <wchar.h>
#include <sys/cygwin.h>
#include "symfile.h"
#include "objfiles.h"
#include "gdb_bfd.h"
-#include "gdb_obstack.h"
+#include "gdbsupport/gdb_obstack.h"
#include "gdbthread.h"
#include "gdbcmd.h"
#include <unistd.h>
#include "gdbsupport/pathstuff.h"
#include "gdbsupport/gdb_wait.h"
#include "nat/windows-nat.h"
+#include "gdbsupport/symbol.h"
using namespace windows_nat;
-#define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
-#define DebugActiveProcessStop dyn_DebugActiveProcessStop
-#define DebugBreakProcess dyn_DebugBreakProcess
-#define DebugSetProcessKillOnExit dyn_DebugSetProcessKillOnExit
-#define EnumProcessModules dyn_EnumProcessModules
-#define EnumProcessModulesEx dyn_EnumProcessModulesEx
-#define GetModuleInformation dyn_GetModuleInformation
-#define LookupPrivilegeValueA dyn_LookupPrivilegeValueA
-#define OpenProcessToken dyn_OpenProcessToken
-#define GetConsoleFontSize dyn_GetConsoleFontSize
-#define GetCurrentConsoleFont dyn_GetCurrentConsoleFont
-#define Wow64SuspendThread dyn_Wow64SuspendThread
-#define Wow64GetThreadContext dyn_Wow64GetThreadContext
-#define Wow64SetThreadContext dyn_Wow64SetThreadContext
-#define Wow64GetThreadSelectorEntry dyn_Wow64GetThreadSelectorEntry
-
-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;
-
-#ifdef __x86_64__
-typedef BOOL WINAPI (EnumProcessModulesEx_ftype) (HANDLE, HMODULE *, DWORD,
- LPDWORD, DWORD);
-static EnumProcessModulesEx_ftype *EnumProcessModulesEx;
-#endif
-
-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;
-
-#ifdef __x86_64__
-typedef DWORD WINAPI (Wow64SuspendThread_ftype) (HANDLE);
-static Wow64SuspendThread_ftype *Wow64SuspendThread;
-
-typedef BOOL WINAPI (Wow64GetThreadContext_ftype) (HANDLE, PWOW64_CONTEXT);
-static Wow64GetThreadContext_ftype *Wow64GetThreadContext;
-
-typedef BOOL WINAPI (Wow64SetThreadContext_ftype) (HANDLE,
- const WOW64_CONTEXT *);
-static Wow64SetThreadContext_ftype *Wow64SetThreadContext;
-
-typedef BOOL WINAPI (Wow64GetThreadSelectorEntry_ftype) (HANDLE, DWORD,
- PLDT_ENTRY);
-static Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
-#endif
+/* The current process. */
+static windows_process_info windows_process;
#undef STARTUPINFO
#undef CreateProcess
#ifndef __CYGWIN__
# define __PMAX (MAX_PATH + 1)
- typedef DWORD WINAPI (GetModuleFileNameEx_ftype) (HANDLE, HMODULE, LPSTR, DWORD);
- static GetModuleFileNameEx_ftype *GetModuleFileNameEx;
+# define GetModuleFileNameEx GetModuleFileNameExA
# define STARTUPINFO STARTUPINFOA
# define CreateProcess CreateProcessA
-# define GetModuleFileNameEx_name "GetModuleFileNameExA"
-# define bad_GetModuleFileNameEx bad_GetModuleFileNameExA
#else
# define __PMAX PATH_MAX
/* The starting and ending address of the cygwin1.dll text segment. */
static CORE_ADDR cygwin_load_end;
# define __USEWIDE
typedef wchar_t cygwin_buf_t;
- typedef DWORD WINAPI (GetModuleFileNameEx_ftype) (HANDLE, HMODULE,
- LPWSTR, DWORD);
- static GetModuleFileNameEx_ftype *GetModuleFileNameEx;
+# define GetModuleFileNameEx GetModuleFileNameExW
# define STARTUPINFO STARTUPINFOW
# define CreateProcess CreateProcessW
-# define GetModuleFileNameEx_name "GetModuleFileNameExW"
-# define bad_GetModuleFileNameEx bad_GetModuleFileNameExW
#endif
static int have_saved_context; /* True if we've saved context from a
#endif
#define CONTEXT_DEBUGGER_DR CONTEXT_FULL | CONTEXT_FLOATING_POINT \
- | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
- | CONTEXT_EXTENDED_REGISTERS
+ | CONTEXT_SEGMENTS | CONTEXT_DEBUG_REGISTERS \
+ | CONTEXT_EXTENDED_REGISTERS
static uintptr_t dr[8];
-static int debug_registers_changed;
-static int debug_registers_used;
static int windows_initialization_done;
#define DR6_CLEAR_VALUE 0xffff0ff0
#endif
#define CHECK(x) check (x, __FILE__,__LINE__)
-#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
-#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
-#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
-#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
+#define DEBUG_EXEC(fmt, ...) \
+ debug_prefixed_printf_cond (debug_exec, "windows exec", fmt, ## __VA_ARGS__)
+#define DEBUG_EVENTS(fmt, ...) \
+ debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
+ ## __VA_ARGS__)
+#define DEBUG_MEM(fmt, ...) \
+ debug_prefixed_printf_cond (debug_memory, "windows mem", fmt, \
+ ## __VA_ARGS__)
+#define DEBUG_EXCEPT(fmt, ...) \
+ debug_prefixed_printf_cond (debug_exceptions, "windows except", fmt, \
+ ## __VA_ARGS__)
static void cygwin_set_dr (int i, CORE_ADDR addr);
static void cygwin_set_dr7 (unsigned long val);
static unsigned long cygwin_get_dr6 (void);
static unsigned long cygwin_get_dr7 (void);
-static std::vector<windows_thread_info *> thread_list;
+static std::vector<std::unique_ptr<windows_thread_info>> thread_list;
/* Counts of things. */
static int saw_create;
static int open_process_used = 0;
#ifdef __x86_64__
-static bool wow64_process = false;
-static bool ignore_first_breakpoint = false;
+static void *wow64_dbgbreak;
#endif
/* User options. */
void resume (ptid_t, int , enum gdb_signal) override;
- ptid_t wait (ptid_t, struct target_waitstatus *, int) override;
+ ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
void fetch_registers (struct regcache *, int) override;
void store_registers (struct regcache *, int) override;
bool stopped_by_sw_breakpoint () override
{
- return current_windows_thread->stopped_at_software_breakpoint;
+ windows_thread_info *th
+ = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
+ return th->stopped_at_software_breakpoint;
}
bool supports_stopped_by_sw_breakpoint () override
char *pid_to_exec_file (int pid) override;
- ptid_t get_ada_task_ptid (long lwp, long thread) override;
+ ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
bool get_tib_address (ptid_t ptid, CORE_ADDR *addr) override;
const char *thread_name (struct thread_info *) override;
int get_windows_debug_event (int pid, struct target_waitstatus *ourstatus);
+
+ void do_initial_windows_stuff (DWORD pid, bool attaching);
};
static windows_nat_target the_windows_nat_target;
check (BOOL ok, const char *file, int line)
{
if (!ok)
- printf_filtered ("error return %s:%d was %u\n", file, line,
- (unsigned) GetLastError ());
+ gdb_printf ("error return %s:%d was %u\n", file, line,
+ (unsigned) GetLastError ());
}
/* See nat/windows-nat.h. */
windows_thread_info *
-windows_nat::thread_rec (ptid_t ptid, thread_disposition_type disposition)
+windows_nat::windows_process_info::thread_rec
+ (ptid_t ptid, thread_disposition_type disposition)
{
- for (windows_thread_info *th : thread_list)
+ for (auto &th : thread_list)
if (th->tid == ptid.lwp ())
{
if (!th->suspended)
break;
}
}
- return th;
+ return th.get ();
}
return NULL;
gdb_assert (ptid.lwp () != 0);
- if ((th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT)))
+ if ((th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT)))
return th;
CORE_ADDR base = (CORE_ADDR) (uintptr_t) tlb;
#ifdef __x86_64__
/* For WOW64 processes, this is actually the pointer to the 64bit TIB,
and the 32bit TIB is exactly 2 pages after it. */
- if (wow64_process)
+ if (windows_process.wow64_process)
base += 0x2000;
#endif
th = new windows_thread_info (ptid.lwp (), h, base);
- thread_list.push_back (th);
+ thread_list.emplace_back (th);
/* Add this new thread to the list of threads.
else
add_thread (&the_windows_nat_target, ptid);
- /* Set the debug registers for the new thread if they are used. */
- if (debug_registers_used)
- {
-#ifdef __x86_64__
- if (wow64_process)
- {
- /* Only change the value of the debug registers. */
- th->wow64_context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
- CHECK (Wow64GetThreadContext (th->h, &th->wow64_context));
- th->wow64_context.Dr0 = dr[0];
- th->wow64_context.Dr1 = dr[1];
- th->wow64_context.Dr2 = dr[2];
- th->wow64_context.Dr3 = dr[3];
- th->wow64_context.Dr6 = DR6_CLEAR_VALUE;
- th->wow64_context.Dr7 = dr[7];
- CHECK (Wow64SetThreadContext (th->h, &th->wow64_context));
- th->wow64_context.ContextFlags = 0;
- }
- else
-#endif
- {
- /* Only change the value of the debug registers. */
- th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
- CHECK (GetThreadContext (th->h, &th->context));
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- th->context.Dr6 = DR6_CLEAR_VALUE;
- th->context.Dr7 = dr[7];
- CHECK (SetThreadContext (th->h, &th->context));
- th->context.ContextFlags = 0;
- }
- }
+ /* It's simplest to always set this and update the debug
+ registers. */
+ th->debug_registers_changed = true;
+
return th;
}
static void
windows_init_thread_list (void)
{
- DEBUG_EVENTS (("gdb: windows_init_thread_list\n"));
- init_thread_list ();
-
- for (windows_thread_info *here : thread_list)
- delete here;
-
+ DEBUG_EVENTS ("called");
thread_list.clear ();
}
here as well. */
if (info_verbose)
- printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (ptid).c_str ());
+ gdb_printf ("[Deleting %s]\n", target_pid_to_str (ptid).c_str ());
else if (print_thread_events && !main_thread_p)
- printf_unfiltered (_("[%s exited with code %u]\n"),
- target_pid_to_str (ptid).c_str (),
- (unsigned) exit_code);
+ gdb_printf (_("[%s exited with code %u]\n"),
+ target_pid_to_str (ptid).c_str (),
+ (unsigned) exit_code);
delete_thread (find_thread_ptid (&the_windows_nat_target, ptid));
auto iter = std::find_if (thread_list.begin (), thread_list.end (),
- [=] (windows_thread_info *th)
+ [=] (auto &th)
{
return th->tid == id;
});
if (iter != thread_list.end ())
- {
- delete *iter;
- thread_list.erase (iter);
- }
+ thread_list.erase (iter);
}
/* Fetches register number R from the given windows_thread_info,
char *context_ptr = (char *) &th->context;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
context_ptr = (char *) &th->wow64_context;
#endif
char *context_offset = context_ptr + mappings[r];
struct gdbarch *gdbarch = regcache->arch ();
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
gdb_assert (!gdbarch_read_pc_p (gdbarch));
gdb_assert (gdbarch_pc_regnum (gdbarch) >= 0);
else
{
if (th->stopped_at_software_breakpoint
+ && !th->pc_adjusted
&& r == gdbarch_pc_regnum (gdbarch))
{
int size = register_size (gdbarch, r);
value -= gdbarch_decr_pc_after_break (gdbarch);
memcpy (context_offset, &value, size);
}
+ /* Make sure we only rewrite the PC a single time. */
+ th->pc_adjusted = true;
}
regcache->raw_supply (r, context_offset);
}
void
windows_nat_target::fetch_registers (struct regcache *regcache, int r)
{
- windows_thread_info *th = thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
/* Check if TH exists. Windows sometimes uses a non-existent
thread id in its events. */
else
#endif
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
th->wow64_context.ContextFlags = CONTEXT_DEBUGGER_DR;
CHECK (Wow64GetThreadContext (th->h, &th->wow64_context));
/* Copy dr values from that thread.
But only if there were not modified since last stop.
PR gdb/2388 */
- if (!debug_registers_changed)
+ if (!th->debug_registers_changed)
{
dr[0] = th->wow64_context.Dr0;
dr[1] = th->wow64_context.Dr1;
/* Copy dr values from that thread.
But only if there were not modified since last stop.
PR gdb/2388 */
- if (!debug_registers_changed)
+ if (!th->debug_registers_changed)
{
dr[0] = th->context.Dr0;
dr[1] = th->context.Dr1;
char *context_ptr = (char *) &th->context;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
context_ptr = (char *) &th->wow64_context;
#endif
void
windows_nat_target::store_registers (struct regcache *regcache, int r)
{
- windows_thread_info *th = thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
/* Check if TH exists. Windows sometimes uses a non-existent
thread id in its events. */
}
/* Maintain a linked list of "so" information. */
-struct lm_info_windows : public lm_info_base
+struct windows_solib
{
LPVOID load_addr = 0;
CORE_ADDR text_offset = 0;
+
+ /* Original name. */
+ std::string original_name;
+ /* Expanded form of the name. */
+ std::string name;
};
-static struct so_list solib_start, *solib_end;
+static std::vector<windows_solib> solibs;
+
+/* See nat/windows-nat.h. */
-static struct so_list *
+static windows_solib *
windows_make_so (const char *name, LPVOID load_addr)
{
- struct so_list *so;
char *p;
#ifndef __CYGWIN__
char buf[__PMAX];
#endif
}
#endif
- so = XCNEW (struct so_list);
- lm_info_windows *li = new lm_info_windows;
- so->lm_info = li;
- li->load_addr = load_addr;
- strcpy (so->so_original_name, name);
+ solibs.emplace_back ();
+ windows_solib *so = &solibs.back ();
+ so->load_addr = load_addr;
+ so->original_name = name;
#ifndef __CYGWIN__
- strcpy (so->so_name, buf);
+ so->name = buf;
#else
if (buf[0])
- cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
- SO_NAME_MAX_PATH_SIZE);
+ {
+ char name[SO_NAME_MAX_PATH_SIZE];
+ cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, name,
+ SO_NAME_MAX_PATH_SIZE);
+ so->name = name;
+ }
else
{
char *rname = realpath (name, NULL);
if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
{
- strcpy (so->so_name, rname);
+ so->name = rname;
free (rname);
}
else
- error (_("dll path too long"));
+ {
+ warning (_("dll path for \"%s\" too long or inaccessible"), name);
+ so->name = so->original_name;
+ }
}
/* Record cygwin1.dll .text start/end. */
- p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
- if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
+ size_t len = sizeof ("/cygwin1.dll") - 1;
+ if (so->name.size () >= len
+ && strcasecmp (so->name.c_str () + so->name.size () - len,
+ "/cygwin1.dll") == 0)
{
asection *text = NULL;
- gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->so_name, "pei-i386", -1));
+ gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->name, "pei-i386"));
if (abfd == NULL)
return so;
/* See nat/windows-nat.h. */
void
-windows_nat::handle_load_dll ()
+windows_nat::windows_process_info::handle_load_dll (const char *dll_name,
+ LPVOID base)
{
- LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
- const char *dll_name;
-
- /* Try getting the DLL name via the lpImageName field of the event.
- Note that Microsoft documents this fields as strictly optional,
- in the sense that it might be NULL. And the first DLL event in
- particular is explicitly documented as "likely not pass[ed]"
- (source: MSDN LOAD_DLL_DEBUG_INFO structure). */
- dll_name = get_image_name (current_process_handle,
- event->lpImageName, event->fUnicode);
- if (!dll_name)
- return;
-
- solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll);
- solib_end = solib_end->next;
-
- lm_info_windows *li = (lm_info_windows *) solib_end->lm_info;
-
- DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name,
- host_address_to_string (li->load_addr)));
-}
-
-static void
-windows_free_so (struct so_list *so)
-{
- lm_info_windows *li = (lm_info_windows *) so->lm_info;
-
- delete li;
- xfree (so);
+ windows_solib *solib = windows_make_so (dll_name, base);
+ DEBUG_EVENTS ("Loading dll \"%s\" at %s.", solib->name.c_str (),
+ host_address_to_string (solib->load_addr));
}
/* See nat/windows-nat.h. */
void
-windows_nat::handle_unload_dll ()
+windows_nat::windows_process_info::handle_unload_dll ()
{
LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
- struct so_list *so;
- for (so = &solib_start; so->next != NULL; so = so->next)
+ auto iter = std::remove_if (solibs.begin (), solibs.end (),
+ [&] (windows_solib &lib)
{
- lm_info_windows *li_next = (lm_info_windows *) so->next->lm_info;
-
- if (li_next->load_addr == lpBaseOfDll)
+ if (lib.load_addr == lpBaseOfDll)
{
- struct so_list *sodel = so->next;
-
- so->next = sodel->next;
- if (!so->next)
- solib_end = so;
- DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name));
-
- windows_free_so (sodel);
- return;
+ DEBUG_EVENTS ("Unloading dll \"%s\".", lib.name.c_str ());
+ return true;
}
+ return false;
+ });
+
+ if (iter != solibs.end ())
+ {
+ solibs.erase (iter, solibs.end ());
+ return;
}
/* We did not find any DLL that was previously loaded at this address,
host_address_to_string (lpBaseOfDll));
}
-/* Call FUNC wrapped in a TRY/CATCH that swallows all GDB
- exceptions. */
-
-static void
-catch_errors (void (*func) ())
-{
- try
- {
- func ();
- }
- catch (const gdb_exception &ex)
- {
- exception_print (gdb_stderr, ex);
- }
-}
-
/* Clear list of loaded DLLs. */
static void
windows_clear_solib (void)
{
- struct so_list *so;
-
- for (so = solib_start.next; so; so = solib_start.next)
- {
- solib_start.next = so->next;
- windows_free_so (so);
- }
-
- solib_end = &solib_start;
+ solibs.clear ();
}
static void
/* See nat/windows-nat.h. */
int
-windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus)
+windows_nat::windows_process_info::handle_output_debug_string
+ (struct target_waitstatus *ourstatus)
{
- gdb::unique_xmalloc_ptr<char> s;
int retval = 0;
- if (!target_read_string
- ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
- &s, 1024, 0)
- || !s || !*(s.get ()))
+ gdb::unique_xmalloc_ptr<char> s
+ = (target_read_string
+ ((CORE_ADDR) (uintptr_t) current_event.u.DebugString.lpDebugStringData,
+ 1024));
+ if (s == nullptr || !*(s.get ()))
/* nothing to do */;
else if (!startswith (s.get (), _CYGWIN_SIGNAL_STRING))
{
int sig = strtol (s.get () + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
gdb_signal gotasig = gdb_signal_from_host (sig);
- ourstatus->value.sig = gotasig;
if (gotasig)
{
LPCVOID x;
SIZE_T n;
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->set_stopped (gotasig);
retval = strtoul (p, &p, 0);
if (!retval)
retval = current_event.dwThreadId;
LDT_ENTRY info;
BOOL ret;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
ret = Wow64GetThreadSelectorEntry (thread, sel, &info);
else
#endif
if (ret)
{
int base, limit;
- printf_filtered ("0x%03x: ", (unsigned) sel);
+ gdb_printf ("0x%03x: ", (unsigned) sel);
if (!info.HighWord.Bits.Pres)
{
- puts_filtered ("Segment not present\n");
+ gdb_puts ("Segment not present\n");
return 0;
}
base = (info.HighWord.Bits.BaseHi << 24) +
limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
if (info.HighWord.Bits.Granularity)
limit = (limit << 12) | 0xfff;
- printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
+ gdb_printf ("base=0x%08x limit=0x%08x", base, limit);
if (info.HighWord.Bits.Default_Big)
- puts_filtered(" 32-bit ");
+ gdb_puts(" 32-bit ");
else
- puts_filtered(" 16-bit ");
+ gdb_puts(" 16-bit ");
switch ((info.HighWord.Bits.Type & 0xf) >> 1)
{
case 0:
- puts_filtered ("Data (Read-Only, Exp-up");
+ gdb_puts ("Data (Read-Only, Exp-up");
break;
case 1:
- puts_filtered ("Data (Read/Write, Exp-up");
+ gdb_puts ("Data (Read/Write, Exp-up");
break;
case 2:
- puts_filtered ("Unused segment (");
+ gdb_puts ("Unused segment (");
break;
case 3:
- puts_filtered ("Data (Read/Write, Exp-down");
+ gdb_puts ("Data (Read/Write, Exp-down");
break;
case 4:
- puts_filtered ("Code (Exec-Only, N.Conf");
+ gdb_puts ("Code (Exec-Only, N.Conf");
break;
case 5:
- puts_filtered ("Code (Exec/Read, N.Conf");
+ gdb_puts ("Code (Exec/Read, N.Conf");
break;
case 6:
- puts_filtered ("Code (Exec-Only, Conf");
+ gdb_puts ("Code (Exec-Only, Conf");
break;
case 7:
- puts_filtered ("Code (Exec/Read, Conf");
+ gdb_puts ("Code (Exec/Read, Conf");
break;
default:
- printf_filtered ("Unknown type 0x%lx",
- (unsigned long) info.HighWord.Bits.Type);
+ gdb_printf ("Unknown type 0x%lx",
+ (unsigned long) info.HighWord.Bits.Type);
}
if ((info.HighWord.Bits.Type & 0x1) == 0)
- puts_filtered(", N.Acc");
- puts_filtered (")\n");
+ gdb_puts(", N.Acc");
+ gdb_puts (")\n");
if ((info.HighWord.Bits.Type & 0x10) == 0)
- puts_filtered("System selector ");
- printf_filtered ("Priviledge level = %ld. ",
- (unsigned long) info.HighWord.Bits.Dpl);
+ gdb_puts("System selector ");
+ gdb_printf ("Priviledge level = %ld. ",
+ (unsigned long) info.HighWord.Bits.Dpl);
if (info.HighWord.Bits.Granularity)
- puts_filtered ("Page granular.\n");
+ gdb_puts ("Page granular.\n");
else
- puts_filtered ("Byte granular.\n");
+ gdb_puts ("Byte granular.\n");
return 1;
}
else
{
DWORD err = GetLastError ();
if (err == ERROR_NOT_SUPPORTED)
- printf_filtered ("Function not supported\n");
+ gdb_printf ("Function not supported\n");
else
- printf_filtered ("Invalid selector 0x%x.\n", (unsigned) sel);
+ gdb_printf ("Invalid selector 0x%x.\n", (unsigned) sel);
return 0;
}
}
static void
display_selectors (const char * args, int from_tty)
{
- if (!current_windows_thread)
+ if (inferior_ptid == null_ptid)
{
- puts_filtered ("Impossible to display selectors now.\n");
+ gdb_puts ("Impossible to display selectors now.\n");
return;
}
+
+ windows_thread_info *current_windows_thread
+ = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
+
if (!args)
{
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
- puts_filtered ("Selector $cs\n");
+ gdb_puts ("Selector $cs\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegCs);
- puts_filtered ("Selector $ds\n");
+ gdb_puts ("Selector $ds\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegDs);
- puts_filtered ("Selector $es\n");
+ gdb_puts ("Selector $es\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegEs);
- puts_filtered ("Selector $ss\n");
+ gdb_puts ("Selector $ss\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegSs);
- puts_filtered ("Selector $fs\n");
+ gdb_puts ("Selector $fs\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegFs);
- puts_filtered ("Selector $gs\n");
+ gdb_puts ("Selector $gs\n");
display_selector (current_windows_thread->h,
current_windows_thread->wow64_context.SegGs);
}
else
#endif
{
- puts_filtered ("Selector $cs\n");
+ gdb_puts ("Selector $cs\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegCs);
- puts_filtered ("Selector $ds\n");
+ gdb_puts ("Selector $ds\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegDs);
- puts_filtered ("Selector $es\n");
+ gdb_puts ("Selector $es\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegEs);
- puts_filtered ("Selector $ss\n");
+ gdb_puts ("Selector $ss\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegSs);
- puts_filtered ("Selector $fs\n");
+ gdb_puts ("Selector $fs\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegFs);
- puts_filtered ("Selector $gs\n");
+ gdb_puts ("Selector $gs\n");
display_selector (current_windows_thread->h,
current_windows_thread->context.SegGs);
}
{
int sel;
sel = parse_and_eval_long (args);
- printf_filtered ("Selector \"%s\"\n",args);
+ gdb_printf ("Selector \"%s\"\n",args);
display_selector (current_windows_thread->h, sel);
}
}
/* See nat/windows-nat.h. */
bool
-windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+windows_nat::windows_process_info::handle_access_violation
+ (const EXCEPTION_RECORD *rec)
{
- if (rec->NumberParameters >= 3
- && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
- {
- DWORD named_thread_id;
- windows_thread_info *named_thread;
- CORE_ADDR thread_name_target;
-
- 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 (ptid_t (current_event.dwProcessId,
- named_thread_id, 0),
- DONT_INVALIDATE_CONTEXT);
- if (named_thread != NULL)
- {
- int thread_name_len;
- gdb::unique_xmalloc_ptr<char> thread_name;
-
- thread_name_len = target_read_string (thread_name_target,
- &thread_name, 1025, NULL);
- if (thread_name_len > 0)
- {
- thread_name.get ()[thread_name_len - 1] = '\0';
- named_thread->name = std::move (thread_name);
- }
- }
-
- return true;
- }
-
+#ifdef __CYGWIN__
+ /* See if the access violation happened within the cygwin DLL
+ itself. Cygwin uses a kind of exception handling to deal with
+ passed-in invalid addresses. gdb should not treat these as real
+ SEGVs since they will be silently handled by cygwin. A real SEGV
+ will (theoretically) be caught by cygwin later in the process and
+ will be sent as a 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) rec->ExceptionAddress;
+
+ if ((!cygwin_exceptions && (addr >= cygwin_load_start
+ && addr < cygwin_load_end))
+ || (find_pc_partial_function (addr, &fn, NULL, NULL)
+ && startswith (fn, "KERNEL32!IsBad")))
+ return true;
+#endif
return false;
}
{
BOOL res;
- desired_stop_thread_id = id;
+ windows_process.desired_stop_thread_id = id;
- if (matching_pending_stop (debug_events))
+ if (windows_process.matching_pending_stop (debug_events))
return TRUE;
- for (windows_thread_info *th : thread_list)
+ for (auto &th : thread_list)
if (id == -1 || id == (int) th->tid)
{
- if (!th->suspended)
- continue;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
- if (debug_registers_changed)
+ if (th->debug_registers_changed)
{
th->wow64_context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
th->wow64_context.Dr0 = dr[0];
th->wow64_context.Dr3 = dr[3];
th->wow64_context.Dr6 = DR6_CLEAR_VALUE;
th->wow64_context.Dr7 = dr[7];
+ th->debug_registers_changed = false;
}
if (th->wow64_context.ContextFlags)
{
else
#endif
{
- if (debug_registers_changed)
+ if (th->debug_registers_changed)
{
th->context.ContextFlags |= CONTEXT_DEBUG_REGISTERS;
th->context.Dr0 = dr[0];
th->context.Dr3 = dr[3];
th->context.Dr6 = DR6_CLEAR_VALUE;
th->context.Dr7 = dr[7];
+ th->debug_registers_changed = false;
}
if (th->context.ContextFlags)
{
" (ContinueDebugEvent failed, error %u)"),
(unsigned int) GetLastError ());
- debug_registers_changed = 0;
return res;
}
static DWORD
fake_create_process (void)
{
- current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
- current_event.dwProcessId);
- if (current_process_handle != NULL)
+ windows_process.handle
+ = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
+ windows_process.current_event.dwProcessId);
+ if (windows_process.handle != NULL)
open_process_used = 1;
else
{
(unsigned) GetLastError ());
/* We can not debug anything in that case. */
}
- current_windows_thread
- = windows_add_thread (ptid_t (current_event.dwProcessId,
- current_event.dwThreadId, 0),
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase,
- true /* main_thread_p */);
- return current_event.dwThreadId;
+ windows_add_thread (ptid_t (windows_process.current_event.dwProcessId, 0,
+ windows_process.current_event.dwThreadId),
+ windows_process.current_event.u.CreateThread.hThread,
+ windows_process.current_event.u.CreateThread.lpThreadLocalBase,
+ true /* main_thread_p */);
+ return windows_process.current_event.dwThreadId;
}
void
if (sig != GDB_SIGNAL_0)
{
- if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
+ if (windows_process.current_event.dwDebugEventCode
+ != EXCEPTION_DEBUG_EVENT)
{
- DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
+ DEBUG_EXCEPT ("Cannot continue with signal %d here.", sig);
}
- else if (sig == last_sig)
+ else if (sig == windows_process.last_sig)
continue_status = DBG_EXCEPTION_NOT_HANDLED;
else
#if 0
}
if (continue_status == DBG_CONTINUE)
{
- DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
+ DEBUG_EXCEPT ("Cannot continue with signal %d.", sig);
}
}
#endif
- DEBUG_EXCEPT(("Can only continue with received signal %d.\n",
- last_sig));
+ DEBUG_EXCEPT ("Can only continue with received signal %d.",
+ windows_process.last_sig);
}
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
- DEBUG_EXEC (("gdb: windows_resume (pid=%d, tid=0x%x, step=%d, sig=%d);\n",
- ptid.pid (), (unsigned) ptid.lwp (), step, sig));
+ DEBUG_EXEC ("pid=%d, tid=0x%x, step=%d, sig=%d",
+ ptid.pid (), (unsigned) ptid.lwp (), step, sig);
/* Get context for currently selected thread. */
- th = thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
+ th = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
if (th)
{
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
if (step)
{
if (th->wow64_context.ContextFlags)
{
- if (debug_registers_changed)
+ if (th->debug_registers_changed)
{
th->wow64_context.Dr0 = dr[0];
th->wow64_context.Dr1 = dr[1];
th->wow64_context.Dr3 = dr[3];
th->wow64_context.Dr6 = DR6_CLEAR_VALUE;
th->wow64_context.Dr7 = dr[7];
+ th->debug_registers_changed = false;
}
CHECK (Wow64SetThreadContext (th->h, &th->wow64_context));
th->wow64_context.ContextFlags = 0;
if (th->context.ContextFlags)
{
- if (debug_registers_changed)
+ if (th->debug_registers_changed)
{
th->context.Dr0 = dr[0];
th->context.Dr1 = dr[1];
th->context.Dr3 = dr[3];
th->context.Dr6 = DR6_CLEAR_VALUE;
th->context.Dr7 = dr[7];
+ th->debug_registers_changed = false;
}
CHECK (SetThreadContext (th->h, &th->context));
th->context.ContextFlags = 0;
if (!new_console && !attach_flag)
return TRUE;
- if (!DebugBreakProcess (current_process_handle))
- warning (_("Could not interrupt program. "
- "Press Ctrl-c in the program console."));
+#ifdef __x86_64__
+ if (windows_process.wow64_process)
+ {
+ /* Call DbgUiRemoteBreakin of the 32bit ntdll.dll in the target process.
+ DebugBreakProcess would call the one of the 64bit ntdll.dll, which
+ can't be correctly handled by gdb. */
+ if (wow64_dbgbreak == nullptr)
+ {
+ CORE_ADDR addr;
+ if (!find_minimal_symbol_address ("ntdll!DbgUiRemoteBreakin",
+ &addr, 0))
+ wow64_dbgbreak = (void *) addr;
+ }
+
+ if (wow64_dbgbreak != nullptr)
+ {
+ HANDLE thread = CreateRemoteThread (windows_process.handle, NULL,
+ 0, (LPTHREAD_START_ROUTINE)
+ wow64_dbgbreak, NULL, 0, NULL);
+ if (thread)
+ CloseHandle (thread);
+ }
+ }
+ else
+#endif
+ {
+ if (!DebugBreakProcess (windows_process.handle))
+ warning (_("Could not interrupt program. "
+ "Press Ctrl-c in the program console."));
+ }
/* Return true to tell that Ctrl-C has been handled. */
return TRUE;
}
-/* A wrapper for WaitForDebugEvent that sets "last_wait_event"
- appropriately. */
-static BOOL
-wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
-{
- BOOL result = WaitForDebugEvent (event, timeout);
- if (result)
- last_wait_event = *event;
- return result;
-}
-
/* Get the next event from the child. Returns a non-zero thread id if the event
requires handling by WFI (or whatever). */
{
BOOL debug_event;
DWORD continue_status, event_code;
- windows_thread_info *th;
- static windows_thread_info dummy_thread_info (0, 0, 0);
DWORD thread_id = 0;
/* If there is a relevant pending stop, report it now. See the
comment by the definition of "pending_stops" for details on why
this is needed. */
- for (auto iter = pending_stops.begin ();
- iter != pending_stops.end ();
- ++iter)
+ gdb::optional<pending_stop> stop
+ = windows_process.fetch_pending_stop (debug_events);
+ if (stop.has_value ())
{
- if (desired_stop_thread_id == -1
- || desired_stop_thread_id == iter->thread_id)
- {
- thread_id = iter->thread_id;
- *ourstatus = iter->status;
- current_event = iter->event;
-
- inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- current_windows_thread = thread_rec (inferior_ptid,
- INVALIDATE_CONTEXT);
- current_windows_thread->reload_context = 1;
+ thread_id = stop->thread_id;
+ *ourstatus = stop->status;
- DEBUG_EVENTS (("get_windows_debug_event - "
- "pending stop found in 0x%x (desired=0x%x)\n",
- thread_id, desired_stop_thread_id));
+ ptid_t ptid (windows_process.current_event.dwProcessId, thread_id);
+ windows_thread_info *th
+ = windows_process.thread_rec (ptid, INVALIDATE_CONTEXT);
+ th->reload_context = true;
- pending_stops.erase (iter);
- return thread_id;
- }
+ return thread_id;
}
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
+ DEBUG_EVENT *current_event = &windows_process.current_event;
- if (!(debug_event = wait_for_debug_event (¤t_event, 1000)))
+ if (!(debug_event = wait_for_debug_event (&windows_process.current_event,
+ 1000)))
goto out;
continue_status = DBG_CONTINUE;
- event_code = current_event.dwDebugEventCode;
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- th = NULL;
+ event_code = windows_process.current_event.dwDebugEventCode;
+ ourstatus->set_spurious ();
have_saved_context = 0;
switch (event_code)
{
case CREATE_THREAD_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "CREATE_THREAD_DEBUG_EVENT"));
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "CREATE_THREAD_DEBUG_EVENT");
if (saw_create != 1)
{
- inferior *inf = find_inferior_pid (this, current_event.dwProcessId);
+ inferior *inf = find_inferior_pid (this, current_event->dwProcessId);
if (!saw_create && inf->attach_flag)
{
/* Kludge around a Windows bug where first event is a create
break;
}
/* Record the existence of this thread. */
- thread_id = current_event.dwThreadId;
- th = windows_add_thread
- (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase,
+ thread_id = current_event->dwThreadId;
+ windows_add_thread
+ (ptid_t (current_event->dwProcessId, current_event->dwThreadId, 0),
+ current_event->u.CreateThread.hThread,
+ current_event->u.CreateThread.lpThreadLocalBase,
false /* main_thread_p */);
break;
case EXIT_THREAD_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXIT_THREAD_DEBUG_EVENT"));
- windows_delete_thread (ptid_t (current_event.dwProcessId,
- current_event.dwThreadId, 0),
- current_event.u.ExitThread.dwExitCode,
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "EXIT_THREAD_DEBUG_EVENT");
+ windows_delete_thread (ptid_t (current_event->dwProcessId,
+ current_event->dwThreadId, 0),
+ current_event->u.ExitThread.dwExitCode,
false /* main_thread_p */);
- th = &dummy_thread_info;
break;
case CREATE_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "CREATE_PROCESS_DEBUG_EVENT"));
- CloseHandle (current_event.u.CreateProcessInfo.hFile);
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "CREATE_PROCESS_DEBUG_EVENT");
+ CloseHandle (current_event->u.CreateProcessInfo.hFile);
if (++saw_create != 1)
break;
- current_process_handle = current_event.u.CreateProcessInfo.hProcess;
+ windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
/* Add the main thread. */
- th = windows_add_thread
- (ptid_t (current_event.dwProcessId,
- current_event.dwThreadId, 0),
- current_event.u.CreateProcessInfo.hThread,
- current_event.u.CreateProcessInfo.lpThreadLocalBase,
+ windows_add_thread
+ (ptid_t (current_event->dwProcessId,
+ current_event->dwThreadId, 0),
+ current_event->u.CreateProcessInfo.hThread,
+ current_event->u.CreateProcessInfo.lpThreadLocalBase,
true /* main_thread_p */);
- thread_id = current_event.dwThreadId;
+ thread_id = current_event->dwThreadId;
break;
case EXIT_PROCESS_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXIT_PROCESS_DEBUG_EVENT"));
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "EXIT_PROCESS_DEBUG_EVENT");
if (!windows_initialization_done)
{
target_terminal::ours ();
target_mourn_inferior (inferior_ptid);
error (_("During startup program exited with code 0x%x."),
- (unsigned int) current_event.u.ExitProcess.dwExitCode);
+ (unsigned int) current_event->u.ExitProcess.dwExitCode);
}
else if (saw_create == 1)
{
- windows_delete_thread (ptid_t (current_event.dwProcessId,
- current_event.dwThreadId, 0),
+ windows_delete_thread (ptid_t (current_event->dwProcessId,
+ current_event->dwThreadId, 0),
0, true /* main_thread_p */);
- DWORD exit_status = current_event.u.ExitProcess.dwExitCode;
+ DWORD exit_status = current_event->u.ExitProcess.dwExitCode;
/* If the exit status looks like a fatal exception, but we
don't recognize the exception's code, make the original
exit status value available, to avoid losing
int exit_signal
= WIFSIGNALED (exit_status) ? WTERMSIG (exit_status) : -1;
if (exit_signal == -1)
- {
- ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = exit_status;
- }
+ ourstatus->set_exited (exit_status);
else
- {
- ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
- ourstatus->value.sig = gdb_signal_from_host (exit_signal);
- }
- thread_id = current_event.dwThreadId;
+ ourstatus->set_signalled (gdb_signal_from_host (exit_signal));
+
+ thread_id = current_event->dwThreadId;
}
break;
case LOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "LOAD_DLL_DEBUG_EVENT"));
- CloseHandle (current_event.u.LoadDll.hFile);
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "LOAD_DLL_DEBUG_EVENT");
+ CloseHandle (current_event->u.LoadDll.hFile);
if (saw_create != 1 || ! windows_initialization_done)
break;
- catch_errors (handle_load_dll);
- ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.integer = 0;
- thread_id = current_event.dwThreadId;
+ try
+ {
+ windows_process.dll_loaded_event ();
+ }
+ catch (const gdb_exception &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ }
+ ourstatus->set_loaded ();
+ thread_id = current_event->dwThreadId;
break;
case UNLOAD_DLL_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "UNLOAD_DLL_DEBUG_EVENT"));
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "UNLOAD_DLL_DEBUG_EVENT");
if (saw_create != 1 || ! windows_initialization_done)
break;
- catch_errors (handle_unload_dll);
- ourstatus->kind = TARGET_WAITKIND_LOADED;
- ourstatus->value.integer = 0;
- thread_id = current_event.dwThreadId;
+ try
+ {
+ windows_process.handle_unload_dll ();
+ }
+ catch (const gdb_exception &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ }
+ ourstatus->set_loaded ();
+ thread_id = current_event->dwThreadId;
break;
case EXCEPTION_DEBUG_EVENT:
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "EXCEPTION_DEBUG_EVENT"));
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "EXCEPTION_DEBUG_EVENT");
if (saw_create != 1)
break;
- switch (handle_exception (ourstatus, debug_exceptions))
+ switch (windows_process.handle_exception (ourstatus, debug_exceptions))
{
case HANDLE_EXCEPTION_UNHANDLED:
default:
continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
case HANDLE_EXCEPTION_HANDLED:
- thread_id = current_event.dwThreadId;
+ thread_id = current_event->dwThreadId;
break;
case HANDLE_EXCEPTION_IGNORED:
continue_status = DBG_CONTINUE;
break;
case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */
- DEBUG_EVENTS (("gdb: kernel event for pid=%u tid=0x%x code=%s)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- "OUTPUT_DEBUG_STRING_EVENT"));
+ DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ "OUTPUT_DEBUG_STRING_EVENT");
if (saw_create != 1)
break;
- thread_id = handle_output_debug_string (ourstatus);
+ thread_id = windows_process.handle_output_debug_string (ourstatus);
break;
default:
if (saw_create != 1)
break;
- printf_unfiltered ("gdb: kernel event for pid=%u tid=0x%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId);
- printf_unfiltered (" unknown event code %u\n",
- (unsigned) current_event.dwDebugEventCode);
+ gdb_printf ("gdb: kernel event for pid=%u tid=0x%x\n",
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId);
+ gdb_printf (" unknown event code %u\n",
+ (unsigned) current_event->dwDebugEventCode);
break;
}
if (!thread_id || saw_create != 1)
{
- CHECK (windows_continue (continue_status, desired_stop_thread_id, 0));
+ CHECK (windows_continue (continue_status,
+ windows_process.desired_stop_thread_id, 0));
}
- else if (desired_stop_thread_id != -1 && desired_stop_thread_id != thread_id)
+ else if (windows_process.desired_stop_thread_id != -1
+ && windows_process.desired_stop_thread_id != thread_id)
{
/* Pending stop. See the comment by the definition of
"pending_stops" for details on why this is needed. */
- DEBUG_EVENTS (("get_windows_debug_event - "
- "unexpected stop in 0x%x (expecting 0x%x)\n",
- thread_id, desired_stop_thread_id));
-
- if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && (current_event.u.Exception.ExceptionRecord.ExceptionCode
- == EXCEPTION_BREAKPOINT)
+ DEBUG_EVENTS ("get_windows_debug_event - "
+ "unexpected stop in 0x%x (expecting 0x%x)",
+ thread_id, windows_process.desired_stop_thread_id);
+
+ if (current_event->dwDebugEventCode == EXCEPTION_DEBUG_EVENT
+ && ((current_event->u.Exception.ExceptionRecord.ExceptionCode
+ == EXCEPTION_BREAKPOINT)
+ || (current_event->u.Exception.ExceptionRecord.ExceptionCode
+ == STATUS_WX86_BREAKPOINT))
&& windows_initialization_done)
{
- ptid_t ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- th = thread_rec (ptid, INVALIDATE_CONTEXT);
+ ptid_t ptid = ptid_t (current_event->dwProcessId, thread_id, 0);
+ windows_thread_info *th
+ = windows_process.thread_rec (ptid, INVALIDATE_CONTEXT);
th->stopped_at_software_breakpoint = true;
+ th->pc_adjusted = false;
}
- pending_stops.push_back ({thread_id, *ourstatus, current_event});
+ windows_process.pending_stops.push_back
+ ({thread_id, *ourstatus, windows_process.current_event});
thread_id = 0;
- CHECK (windows_continue (continue_status, desired_stop_thread_id, 0));
- }
- else
- {
- inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- current_windows_thread = th;
- if (!current_windows_thread)
- current_windows_thread = thread_rec (inferior_ptid,
- INVALIDATE_CONTEXT);
+ CHECK (windows_continue (continue_status,
+ windows_process.desired_stop_thread_id, 0));
}
out:
/* Wait for interesting events to occur in the target process. */
ptid_t
windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
- int options)
+ target_wait_flags options)
{
int pid = -1;
if (retval)
{
- ptid_t result = ptid_t (current_event.dwProcessId, retval, 0);
+ ptid_t result = ptid_t (windows_process.current_event.dwProcessId,
+ retval, 0);
- if (current_windows_thread != nullptr)
+ if (ourstatus->kind () != TARGET_WAITKIND_EXITED
+ && ourstatus->kind () != TARGET_WAITKIND_SIGNALLED)
{
- current_windows_thread->stopped_at_software_breakpoint = false;
- if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && (current_event.u.Exception.ExceptionRecord.ExceptionCode
- == EXCEPTION_BREAKPOINT)
- && windows_initialization_done)
- current_windows_thread->stopped_at_software_breakpoint = true;
+ windows_thread_info *th
+ = windows_process.thread_rec (result, INVALIDATE_CONTEXT);
+
+ if (th != nullptr)
+ {
+ th->stopped_at_software_breakpoint = false;
+ if (windows_process.current_event.dwDebugEventCode
+ == EXCEPTION_DEBUG_EVENT
+ && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
+ == EXCEPTION_BREAKPOINT)
+ || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
+ == STATUS_WX86_BREAKPOINT))
+ && windows_initialization_done)
+ {
+ th->stopped_at_software_breakpoint = true;
+ th->pc_adjusted = false;
+ }
+ }
}
return result;
}
}
-/* Iterate over all DLLs currently mapped by our inferior, and
- add them to our list of solibs. */
-
-static void
-windows_add_all_dlls (void)
-{
- HMODULE dummy_hmodule;
- DWORD cb_needed;
- HMODULE *hmodules;
- int i;
-
-#ifdef __x86_64__
- if (wow64_process)
- {
- if (EnumProcessModulesEx (current_process_handle, &dummy_hmodule,
- sizeof (HMODULE), &cb_needed,
- LIST_MODULES_32BIT) == 0)
- return;
- }
- else
-#endif
- {
- if (EnumProcessModules (current_process_handle, &dummy_hmodule,
- sizeof (HMODULE), &cb_needed) == 0)
- return;
- }
-
- if (cb_needed < 1)
- return;
-
- hmodules = (HMODULE *) alloca (cb_needed);
-#ifdef __x86_64__
- if (wow64_process)
- {
- if (EnumProcessModulesEx (current_process_handle, hmodules,
- cb_needed, &cb_needed,
- LIST_MODULES_32BIT) == 0)
- return;
- }
- else
-#endif
- {
- if (EnumProcessModules (current_process_handle, hmodules,
- cb_needed, &cb_needed) == 0)
- return;
- }
-
- char system_dir[__PMAX];
- char syswow_dir[__PMAX];
- size_t system_dir_len = 0;
- bool convert_syswow_dir = false;
-#ifdef __x86_64__
- if (wow64_process)
-#endif
- {
- /* This fails on 32bit Windows because it has no SysWOW64 directory,
- and in this case a path conversion isn't necessary. */
- UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
- if (len > 0)
- {
- /* Check that we have passed a large enough buffer. */
- gdb_assert (len < sizeof (syswow_dir));
-
- len = GetSystemDirectoryA (system_dir, sizeof (system_dir));
- /* Error check. */
- gdb_assert (len != 0);
- /* Check that we have passed a large enough buffer. */
- gdb_assert (len < sizeof (system_dir));
-
- strcat (system_dir, "\\");
- strcat (syswow_dir, "\\");
- system_dir_len = strlen (system_dir);
-
- convert_syswow_dir = true;
- }
-
- }
- for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
- {
- MODULEINFO mi;
-#ifdef __USEWIDE
- wchar_t dll_name[__PMAX];
- char dll_name_mb[__PMAX];
-#else
- char dll_name[__PMAX];
-#endif
- const char *name;
- if (GetModuleInformation (current_process_handle, hmodules[i],
- &mi, sizeof (mi)) == 0)
- continue;
- if (GetModuleFileNameEx (current_process_handle, hmodules[i],
- dll_name, sizeof (dll_name)) == 0)
- continue;
-#ifdef __USEWIDE
- wcstombs (dll_name_mb, dll_name, __PMAX);
- name = dll_name_mb;
-#else
- name = dll_name;
-#endif
- /* Convert the DLL path of 32bit processes returned by
- GetModuleFileNameEx from the 64bit system directory to the
- 32bit syswow64 directory if necessary. */
- std::string syswow_dll_path;
- if (convert_syswow_dir
- && strncasecmp (name, system_dir, system_dir_len) == 0
- && strchr (name + system_dir_len, '\\') == nullptr)
- {
- syswow_dll_path = syswow_dir;
- syswow_dll_path += name + system_dir_len;
- name = syswow_dll_path.c_str();
- }
-
- solib_end->next = windows_make_so (name, mi.lpBaseOfDll);
- solib_end = solib_end->next;
- }
-}
-
-static void
-do_initial_windows_stuff (struct target_ops *ops, DWORD pid, int attaching)
+void
+windows_nat_target::do_initial_windows_stuff (DWORD pid, bool attaching)
{
int i;
struct inferior *inf;
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
open_process_used = 0;
- debug_registers_changed = 0;
- debug_registers_used = 0;
for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
dr[i] = 0;
#ifdef __CYGWIN__
cygwin_load_start = cygwin_load_end = 0;
#endif
- current_event.dwProcessId = pid;
- memset (¤t_event, 0, sizeof (current_event));
- if (!target_is_pushed (ops))
- push_target (ops);
+ windows_process.current_event.dwProcessId = pid;
+ memset (&windows_process.current_event, 0,
+ sizeof (windows_process.current_event));
+ inf = current_inferior ();
+ if (!inf->target_is_pushed (this))
+ inf->push_target (this);
disable_breakpoints_in_shlibs ();
windows_clear_solib ();
clear_proceed_status (0);
init_wait_for_inferior ();
#ifdef __x86_64__
- ignore_first_breakpoint = !attaching && wow64_process;
+ windows_process.ignore_first_breakpoint
+ = !attaching && windows_process.wow64_process;
- if (!wow64_process)
+ if (!windows_process.wow64_process)
{
windows_set_context_register_offsets (amd64_mappings);
windows_set_segment_register_p (amd64_windows_segment_register_p);
windows_set_segment_register_p (i386_windows_segment_register_p);
}
- inf = current_inferior ();
inferior_appeared (inf, pid);
inf->attach_flag = attaching;
- /* Make the new process the current inferior, so terminal handling
- can rely on it. When attaching, we don't know about any thread
- id here, but that's OK --- nothing should be referencing the
- current thread until we report an event out of windows_wait. */
- inferior_ptid = ptid_t (pid);
-
target_terminal::init ();
target_terminal::inferior ();
windows_initialization_done = 0;
+ ptid_t last_ptid;
+
while (1)
{
struct target_waitstatus status;
- ops->wait (minus_one_ptid, &status, 0);
+ last_ptid = this->wait (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)
+ if (status.kind () != TARGET_WAITKIND_LOADED
+ && status.kind () != TARGET_WAITKIND_SPURIOUS)
break;
- ops->resume (minus_one_ptid, 0, GDB_SIGNAL_0);
+ this->resume (minus_one_ptid, 0, GDB_SIGNAL_0);
}
+ switch_to_thread (find_thread_ptid (this, last_ptid));
+
/* Now that the inferior has been started and all DLLs have been mapped,
we can iterate over all DLLs and load them in.
Rather than try to work around this sort of issue, it is much
simpler to just ignore DLL load/unload events during the startup
phase, and then process them all in one batch now. */
- windows_add_all_dlls ();
+ windows_process.add_all_dlls ();
windows_initialization_done = 1;
return;
pid = parse_pid_to_attach (args);
if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
- {
- printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
- printf_unfiltered ("This can cause attach to "
- "fail on Windows NT/2K/XP\n");
- }
+ warning ("Failed to get SE_DEBUG_NAME privilege\n"
+ "This can cause attach to fail on Windows NT/2K/XP");
windows_init_thread_list ();
ok = DebugActiveProcess (pid);
DebugSetProcessKillOnExit (FALSE);
- if (from_tty)
- {
- const char *exec_file = get_exec_file (0);
-
- if (exec_file)
- printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
- target_pid_to_str (ptid_t (pid)).c_str ());
- else
- printf_unfiltered ("Attaching to %s\n",
- target_pid_to_str (ptid_t (pid)).c_str ());
- }
+ target_announce_attach (from_tty, pid);
#ifdef __x86_64__
HANDLE h = OpenProcess (PROCESS_QUERY_INFORMATION, FALSE, pid);
{
BOOL wow64;
if (IsWow64Process (h, &wow64))
- wow64_process = wow64;
+ windows_process.wow64_process = wow64;
CloseHandle (h);
}
#endif
- do_initial_windows_stuff (this, pid, 1);
+ do_initial_windows_stuff (pid, 1);
target_terminal::ours ();
}
ptid_t ptid = minus_one_ptid;
resume (ptid, 0, GDB_SIGNAL_0);
- if (!DebugActiveProcessStop (current_event.dwProcessId))
+ if (!DebugActiveProcessStop (windows_process.current_event.dwProcessId))
{
error (_("Can't detach process %u (error %u)"),
- (unsigned) current_event.dwProcessId, (unsigned) GetLastError ());
+ (unsigned) windows_process.current_event.dwProcessId,
+ (unsigned) GetLastError ());
detached = 0;
}
DebugSetProcessKillOnExit (FALSE);
- if (detached && from_tty)
- {
- const char *exec_file = get_exec_file (0);
- if (exec_file == 0)
- exec_file = "";
- printf_unfiltered ("Detaching from program: %s, Pid %u\n", exec_file,
- (unsigned) current_event.dwProcessId);
- }
+ if (detached)
+ target_announce_detach (from_tty);
x86_cleanup_dregs ();
- inferior_ptid = null_ptid;
+ switch_to_no_thread ();
detach_inferior (inf);
maybe_unpush_target ();
cbNeeded = 0;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
- if (!EnumProcessModulesEx (current_process_handle, &dh_buf,
- sizeof (HMODULE), &cbNeeded,
- LIST_MODULES_32BIT) || !cbNeeded)
+ if (!EnumProcessModulesEx (windows_process.handle,
+ &dh_buf, sizeof (HMODULE), &cbNeeded,
+ LIST_MODULES_32BIT)
+ || !cbNeeded)
return 0;
}
else
#endif
{
- if (!EnumProcessModules (current_process_handle, &dh_buf,
- sizeof (HMODULE), &cbNeeded) || !cbNeeded)
+ if (!EnumProcessModules (windows_process.handle,
+ &dh_buf, sizeof (HMODULE), &cbNeeded)
+ || !cbNeeded)
return 0;
}
error (_("Error converting executable filename to POSIX: %d."), errno);
}
#else
- len = GetModuleFileNameEx (current_process_handle,
+ len = GetModuleFileNameEx (windows_process.handle,
dh_buf, exe_name_ret, exe_name_max_len);
if (len == 0)
error (_("Error getting executable filename: %u."),
{
struct inferior *inf = current_inferior ();
- printf_unfiltered ("\tUsing the running image of %s %s.\n",
- inf->attach_flag ? "attached" : "child",
- target_pid_to_str (inferior_ptid).c_str ());
+ gdb_printf ("\tUsing the running image of %s %s.\n",
+ inf->attach_flag ? "attached" : "child",
+ target_pid_to_str (inferior_ptid).c_str ());
}
/* Modify CreateProcess parameters for use of a new separate console.
mbstowcs (copy, env[i], len);
equalpos = wcschr (copy, L'=');
if (equalpos)
- *equalpos = L'\0';
+ *equalpos = L'\0';
SetEnvironmentVariableW (copy, NULL);
}
xfree (copy);
PROCESS_INFORMATION pi;
BOOL ret;
DWORD flags = 0;
- const char *inferior_io_terminal = get_inferior_io_terminal ();
+ const std::string &inferior_tty = current_inferior ()->tty ();
if (!exec_file)
error (_("No executable specified, use `target exec'."));
- const char *inferior_cwd = get_inferior_cwd ();
+ const char *inferior_cwd = current_inferior ()->cwd ().c_str ();
std::string expanded_infcwd;
- if (inferior_cwd != NULL)
+ if (*inferior_cwd == '\0')
+ inferior_cwd = nullptr;
+ else
{
expanded_infcwd = gdb_tilde_expand (inferior_cwd);
/* Mirror slashes on inferior's cwd. */
{
sh = get_shell ();
if (cygwin_conv_path (CCP_POSIX_TO_WIN_W, sh, shell, __PMAX) < 0)
- error (_("Error starting executable via shell: %d"), errno);
+ error (_("Error starting executable via shell: %d"), errno);
#ifdef __USEWIDE
len = sizeof (L" -c 'exec '") + mbstowcs (NULL, exec_file, 0)
+ mbstowcs (NULL, allargs, 0) + 2;
w32_env = NULL;
}
- if (!inferior_io_terminal)
+ if (inferior_tty.empty ())
tty = ostdin = ostdout = ostderr = -1;
else
{
- tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
+ tty = open (inferior_tty.c_str (), O_RDWR | O_NOCTTY);
if (tty < 0)
{
- print_sys_errmsg (inferior_io_terminal, errno);
+ print_sys_errmsg (inferior_tty.c_str (), errno);
ostdin = ostdout = ostderr = -1;
}
else
allargs_len = strlen (allargs_copy);
}
/* If not all the standard streams are redirected by the command
- line, use inferior_io_terminal for those which aren't. */
- if (inferior_io_terminal
+ line, use INFERIOR_TTY for those which aren't. */
+ if (!inferior_tty.empty ()
&& !(fd_inp >= 0 && fd_out >= 0 && fd_err >= 0))
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = 0;
sa.bInheritHandle = TRUE;
- tty = CreateFileA (inferior_io_terminal, GENERIC_READ | GENERIC_WRITE,
+ tty = CreateFileA (inferior_tty.c_str (), GENERIC_READ | GENERIC_WRITE,
0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (tty == INVALID_HANDLE_VALUE)
warning (_("Warning: Failed to open TTY %s, error %#x."),
- inferior_io_terminal, (unsigned) GetLastError ());
+ inferior_tty.c_str (), (unsigned) GetLastError ());
}
if (redirected || tty != INVALID_HANDLE_VALUE)
{
#ifdef __x86_64__
BOOL wow64;
if (IsWow64Process (pi.hProcess, &wow64))
- wow64_process = wow64;
+ windows_process.wow64_process = wow64;
#endif
CloseHandle (pi.hThread);
else
saw_create = 0;
- do_initial_windows_stuff (this, pi.dwProcessId, 0);
+ do_initial_windows_stuff (pi.dwProcessId, 0);
/* windows_continue (DBG_CONTINUE, -1, 0); */
}
x86_cleanup_dregs();
if (open_process_used)
{
- CHECK (CloseHandle (current_process_handle));
+ CHECK (CloseHandle (windows_process.handle));
open_process_used = 0;
}
- siginfo_er.ExceptionCode = 0;
+ windows_process.siginfo_er.ExceptionCode = 0;
inf_child_target::mourn_inferior ();
}
void
windows_nat_target::interrupt ()
{
- DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
- CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
+ DEBUG_EVENTS ("GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)");
+ CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT,
+ windows_process.current_event.dwProcessId));
registers_changed (); /* refresh register state */
}
if (writebuf != NULL)
{
- DEBUG_MEM (("gdb: write target memory, %s bytes at %s\n",
- pulongest (len), core_addr_to_string (memaddr)));
- success = WriteProcessMemory (current_process_handle,
+ DEBUG_MEM ("write target memory, %s bytes at %s",
+ pulongest (len), core_addr_to_string (memaddr));
+ success = WriteProcessMemory (windows_process.handle,
(LPVOID) (uintptr_t) memaddr, writebuf,
len, &done);
if (!success)
lasterror = GetLastError ();
- FlushInstructionCache (current_process_handle,
+ FlushInstructionCache (windows_process.handle,
(LPCVOID) (uintptr_t) memaddr, len);
}
else
{
- DEBUG_MEM (("gdb: read target memory, %s bytes at %s\n",
- pulongest (len), core_addr_to_string (memaddr)));
- success = ReadProcessMemory (current_process_handle,
+ DEBUG_MEM ("read target memory, %s bytes at %s",
+ pulongest (len), core_addr_to_string (memaddr));
+ success = ReadProcessMemory (windows_process.handle,
(LPCVOID) (uintptr_t) memaddr, readbuf,
len, &done);
if (!success)
void
windows_nat_target::kill ()
{
- CHECK (TerminateProcess (current_process_handle, 0));
+ CHECK (TerminateProcess (windows_process.handle, 0));
for (;;)
{
if (!windows_continue (DBG_CONTINUE, -1, 1))
break;
- if (!wait_for_debug_event (¤t_event, INFINITE))
+ if (!wait_for_debug_event (&windows_process.current_event, INFINITE))
break;
- if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
+ if (windows_process.current_event.dwDebugEventCode
+ == EXIT_PROCESS_DEBUG_EVENT)
break;
}
void
windows_nat_target::close ()
{
- DEBUG_EVENTS (("gdb: windows_close, inferior_ptid=%d\n",
- inferior_ptid.pid ()));
+ DEBUG_EVENTS ("inferior_ptid=%d\n", inferior_ptid.pid ());
}
/* Convert pid to printable format. */
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len)
{
- struct obstack obstack;
+ auto_obstack obstack;
const char *buf;
LONGEST len_avail;
- struct so_list *so;
if (writebuf)
return TARGET_XFER_E_IO;
- obstack_init (&obstack);
obstack_grow_str (&obstack, "<library-list>\n");
- for (so = solib_start.next; so; so = so->next)
- {
- lm_info_windows *li = (lm_info_windows *) so->lm_info;
-
- windows_xfer_shared_library (so->so_name, (CORE_ADDR)
- (uintptr_t) li->load_addr,
- &li->text_offset,
- target_gdbarch (), &obstack);
- }
+ for (windows_solib &so : solibs)
+ windows_xfer_shared_library (so.name.c_str (),
+ (CORE_ADDR) (uintptr_t) so.load_addr,
+ &so.text_offset,
+ target_gdbarch (), &obstack);
obstack_grow_str0 (&obstack, "</library-list>\n");
buf = (const char *) obstack_finish (&obstack);
memcpy (readbuf, buf + offset, len);
}
- obstack_free (&obstack, NULL);
*xfered_len = (ULONGEST) len;
return len != 0 ? TARGET_XFER_OK : TARGET_XFER_EOF;
}
windows_xfer_siginfo (gdb_byte *readbuf, ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len)
{
- char *buf = (char *) &siginfo_er;
- size_t bufsize = sizeof (siginfo_er);
+ char *buf = (char *) &windows_process.siginfo_er;
+ size_t bufsize = sizeof (windows_process.siginfo_er);
#ifdef __x86_64__
EXCEPTION_RECORD32 er32;
- if (wow64_process)
+ if (windows_process.wow64_process)
{
buf = (char *) &er32;
bufsize = sizeof (er32);
- er32.ExceptionCode = siginfo_er.ExceptionCode;
- er32.ExceptionFlags = siginfo_er.ExceptionFlags;
- er32.ExceptionRecord = (uintptr_t) siginfo_er.ExceptionRecord;
- er32.ExceptionAddress = (uintptr_t) siginfo_er.ExceptionAddress;
- er32.NumberParameters = siginfo_er.NumberParameters;
+ er32.ExceptionCode = windows_process.siginfo_er.ExceptionCode;
+ er32.ExceptionFlags = windows_process.siginfo_er.ExceptionFlags;
+ er32.ExceptionRecord
+ = (uintptr_t) windows_process.siginfo_er.ExceptionRecord;
+ er32.ExceptionAddress
+ = (uintptr_t) windows_process.siginfo_er.ExceptionAddress;
+ er32.NumberParameters = windows_process.siginfo_er.NumberParameters;
int i;
for (i = 0; i < EXCEPTION_MAXIMUM_PARAMETERS; i++)
- er32.ExceptionInformation[i] = siginfo_er.ExceptionInformation[i];
+ er32.ExceptionInformation[i]
+ = windows_process.siginfo_er.ExceptionInformation[i];
}
#endif
- if (siginfo_er.ExceptionCode == 0)
+ if (windows_process.siginfo_er.ExceptionCode == 0)
return TARGET_XFER_E_IO;
if (readbuf == nullptr)
{
windows_thread_info *th;
- th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
+ th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
if (th == NULL)
return false;
}
ptid_t
-windows_nat_target::get_ada_task_ptid (long lwp, long thread)
+windows_nat_target::get_ada_task_ptid (long lwp, ULONGEST thread)
{
return ptid_t (inferior_ptid.pid (), lwp, 0);
}
const char *
windows_nat_target::thread_name (struct thread_info *thr)
{
- return thread_rec (thr->ptid, DONT_INVALIDATE_CONTEXT)->name.get ();
+ windows_thread_info *th
+ = windows_process.thread_rec (thr->ptid,
+ DONT_INVALIDATE_CONTEXT);
+ return th->thread_name ();
}
add_cmd ("selector", class_info, display_selectors,
_("Display selectors infos."),
&info_w32_cmdlist);
+
+ if (!initialize_loadable ())
+ {
+ /* This will probably fail on Windows 9x/Me. Let the user know
+ that we're missing some functionality. */
+ warning(_("\
+cannot automatically find executable file or library to read symbols.\n\
+Use \"file\" or \"dll\" command to load executable/libraries directly."));
+ }
}
/* Hardware watchpoint support, adapted from go32-nat.c code. */
internal_error (__FILE__, __LINE__,
_("Invalid register %d in cygwin_set_dr.\n"), i);
dr[i] = addr;
- debug_registers_changed = 1;
- debug_registers_used = 1;
+
+ for (auto &th : thread_list)
+ th->debug_registers_changed = true;
}
/* Pass the value VAL to the inferior in the DR7 debug control
cygwin_set_dr7 (unsigned long val)
{
dr[7] = (CORE_ADDR) val;
- debug_registers_changed = 1;
- debug_registers_used = 1;
+
+ for (auto &th : thread_list)
+ th->debug_registers_changed = true;
}
/* Get the value of debug register I from the inferior. */
{
gdb_assert (ptid.lwp () != 0);
- return (WaitForSingleObject (thread_rec (ptid, DONT_INVALIDATE_CONTEXT)->h, 0)
- != WAIT_OBJECT_0);
+ windows_thread_info *th
+ = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
+ return WaitForSingleObject (th->h, 0) != WAIT_OBJECT_0;
}
void _initialize_check_for_gdb_ini ();
}
}
}
-
-/* Define dummy functions which always return error for the rare cases where
- these functions could not be found. */
-static BOOL WINAPI
-bad_DebugActiveProcessStop (DWORD w)
-{
- return FALSE;
-}
-static BOOL WINAPI
-bad_DebugBreakProcess (HANDLE w)
-{
- return FALSE;
-}
-static BOOL WINAPI
-bad_DebugSetProcessKillOnExit (BOOL w)
-{
- return FALSE;
-}
-static BOOL WINAPI
-bad_EnumProcessModules (HANDLE w, HMODULE *x, DWORD y, LPDWORD z)
-{
- return FALSE;
-}
-
-#ifdef __USEWIDE
-static DWORD WINAPI
-bad_GetModuleFileNameExW (HANDLE w, HMODULE x, LPWSTR y, DWORD z)
-{
- return 0;
-}
-#else
-static DWORD WINAPI
-bad_GetModuleFileNameExA (HANDLE w, HMODULE x, LPSTR y, DWORD z)
-{
- return 0;
-}
-#endif
-
-static BOOL WINAPI
-bad_GetModuleInformation (HANDLE w, HMODULE x, LPMODULEINFO y, DWORD z)
-{
- return FALSE;
-}
-
-static BOOL WINAPI
-bad_OpenProcessToken (HANDLE w, DWORD x, PHANDLE y)
-{
- return FALSE;
-}
-
-static BOOL WINAPI
-bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
-{
- f->nFont = 0;
- return 1;
-}
-static COORD WINAPI
-bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
-{
- COORD size;
- size.X = 8;
- size.Y = 12;
- return size;
-}
-
-/* Load any functions which may not be available in ancient versions
- of Windows. */
-
-void _initialize_loadable ();
-void
-_initialize_loadable ()
-{
- HMODULE hm = NULL;
-
-#define GPA(m, func) \
- func = (func ## _ftype *) GetProcAddress (m, #func)
-
- hm = LoadLibrary ("kernel32.dll");
- if (hm)
- {
- GPA (hm, DebugActiveProcessStop);
- GPA (hm, DebugBreakProcess);
- GPA (hm, DebugSetProcessKillOnExit);
- GPA (hm, GetConsoleFontSize);
- GPA (hm, DebugActiveProcessStop);
- GPA (hm, GetCurrentConsoleFont);
-#ifdef __x86_64__
- GPA (hm, Wow64SuspendThread);
- GPA (hm, Wow64GetThreadContext);
- GPA (hm, Wow64SetThreadContext);
- GPA (hm, Wow64GetThreadSelectorEntry);
-#endif
- }
-
- /* Set variables to dummy versions of these processes if the function
- wasn't found in kernel32.dll. */
- if (!DebugBreakProcess)
- DebugBreakProcess = bad_DebugBreakProcess;
- if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
- {
- DebugActiveProcessStop = bad_DebugActiveProcessStop;
- DebugSetProcessKillOnExit = bad_DebugSetProcessKillOnExit;
- }
- if (!GetConsoleFontSize)
- GetConsoleFontSize = bad_GetConsoleFontSize;
- if (!GetCurrentConsoleFont)
- GetCurrentConsoleFont = bad_GetCurrentConsoleFont;
-
- /* Load optional functions used for retrieving filename information
- associated with the currently debugged process or its dlls. */
- hm = LoadLibrary ("psapi.dll");
- if (hm)
- {
- GPA (hm, EnumProcessModules);
-#ifdef __x86_64__
- GPA (hm, EnumProcessModulesEx);
-#endif
- GPA (hm, GetModuleInformation);
- GetModuleFileNameEx = (GetModuleFileNameEx_ftype *)
- GetProcAddress (hm, GetModuleFileNameEx_name);
- }
-
- if (!EnumProcessModules || !GetModuleInformation || !GetModuleFileNameEx)
- {
- /* Set variables to dummy versions of these processes if the function
- wasn't found in psapi.dll. */
- EnumProcessModules = bad_EnumProcessModules;
- GetModuleInformation = bad_GetModuleInformation;
- GetModuleFileNameEx = bad_GetModuleFileNameEx;
- /* This will probably fail on Windows 9x/Me. Let the user know
- that we're missing some functionality. */
- warning(_("\
-cannot automatically find executable file or library to read symbols.\n\
-Use \"file\" or \"dll\" command to load executable/libraries directly."));
- }
-
- hm = LoadLibrary ("advapi32.dll");
- if (hm)
- {
- 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
-}