#include "gdbsupport/gdb_wait.h"
#include "nat/windows-nat.h"
-#define STATUS_WX86_BREAKPOINT 0x4000001F
-#define STATUS_WX86_SINGLE_STEP 0x4000001E
+using namespace windows_nat;
#define AdjustTokenPrivileges dyn_AdjustTokenPrivileges
#define DebugActiveProcessStop dyn_DebugActiveProcessStop
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
static unsigned long cygwin_get_dr6 (void);
static unsigned long cygwin_get_dr7 (void);
-static enum gdb_signal last_sig = GDB_SIGNAL_0;
-/* Set if a signal was received from the debugged process. */
-
static std::vector<windows_thread_info *> thread_list;
-/* The process and thread handles for the above context. */
-
-/* The current debug event from WaitForDebugEvent or from a pending
- stop. */
-static DEBUG_EVENT current_event;
-
-/* The most recent event from WaitForDebugEvent. Unlike
- current_event, this is guaranteed never to come from a pending
- stop. This is important because only data from the most recent
- event from WaitForDebugEvent can be used when calling
- ContinueDebugEvent. */
-static DEBUG_EVENT last_wait_event;
-
-static HANDLE current_process_handle; /* Currently executing process */
-static windows_thread_info *current_thread; /* Info on currently selected thread */
-static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
-
/* Counts of things. */
-static int exception_count = 0;
-static int event_count = 0;
static int saw_create;
static int open_process_used = 0;
#ifdef __x86_64__
#endif /* 0 */
-/* The ID of the thread for which we anticipate a stop event.
- Normally this is -1, meaning we'll accept an event in any
- thread. */
-static DWORD desired_stop_thread_id = -1;
-
-/* A single pending stop. See "pending_stops" for more
- information. */
-struct pending_stop
-{
- /* The thread id. */
- DWORD thread_id;
-
- /* The target waitstatus we computed. */
- target_waitstatus status;
-
- /* The event. A few fields of this can be referenced after a stop,
- and it seemed simplest to store the entire event. */
- DEBUG_EVENT event;
-};
-
-/* A vector of pending stops. Sometimes, Windows will report a stop
- on a thread that has been ostensibly suspended. We believe what
- happens here is that two threads hit a breakpoint simultaneously,
- and the Windows kernel queues the stop events. However, this can
- result in the strange effect of trying to single step thread A --
- leaving all other threads suspended -- and then seeing a stop in
- thread B. To handle this scenario, we queue all such "pending"
- stops here, and then process them once the step has completed. See
- PR gdb/22992. */
-static std::vector<pending_stop> pending_stops;
-
struct windows_nat_target final : public x86_nat_target<inf_child_target>
{
void close () override;
bool stopped_by_sw_breakpoint () override
{
- return current_thread->stopped_at_software_breakpoint;
+ return current_windows_thread->stopped_at_software_breakpoint;
}
bool supports_stopped_by_sw_breakpoint () override
(unsigned) GetLastError ());
}
-/* Possible values to pass to 'thread_rec'. */
-enum thread_disposition_type
-{
- /* Do not invalidate the thread's context, and do not suspend the
- thread. */
- DONT_INVALIDATE_CONTEXT,
- /* Invalidate the context, but do not suspend the thread. */
- DONT_SUSPEND,
- /* Invalidate the context and suspend the thread. */
- INVALIDATE_CONTEXT
-};
+/* See nat/windows-nat.h. */
-/* Find a thread record given a thread id. THREAD_DISPOSITION
- controls whether the thread is suspended, and whether the context
- is invalidated. */
-static windows_thread_info *
-thread_rec (DWORD id, enum thread_disposition_type disposition)
+windows_thread_info *
+windows_nat::thread_rec (ptid_t ptid, thread_disposition_type disposition)
{
for (windows_thread_info *th : thread_list)
- if (th->tid == id)
+ if (th->tid == ptid.lwp ())
{
if (!th->suspended)
{
/* Nothing. */
break;
case INVALIDATE_CONTEXT:
- if (id != current_event.dwThreadId)
+ if (ptid.lwp () != current_event.dwThreadId)
th->suspend ();
th->reload_context = true;
break;
windows_add_thread (ptid_t ptid, HANDLE h, void *tlb, bool main_thread_p)
{
windows_thread_info *th;
- DWORD id;
gdb_assert (ptid.lwp () != 0);
- id = ptid.lwp ();
-
- if ((th = thread_rec (id, DONT_INVALIDATE_CONTEXT)))
+ if ((th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT)))
return th;
CORE_ADDR base = (CORE_ADDR) (uintptr_t) tlb;
if (wow64_process)
base += 0x2000;
#endif
- th = new windows_thread_info (id, h, base);
+ th = new windows_thread_info (ptid.lwp (), h, base);
thread_list.push_back (th);
/* Add this new thread to the list of threads.
void
windows_nat_target::fetch_registers (struct regcache *regcache, int r)
{
- DWORD tid = regcache->ptid ().lwp ();
- windows_thread_info *th = thread_rec (tid, INVALIDATE_CONTEXT);
+ windows_thread_info *th = thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
/* Check if TH exists. Windows sometimes uses a non-existent
thread id in its events. */
void
windows_nat_target::store_registers (struct regcache *regcache, int r)
{
- DWORD tid = regcache->ptid ().lwp ();
- windows_thread_info *th = thread_rec (tid, INVALIDATE_CONTEXT);
+ windows_thread_info *th = thread_rec (regcache->ptid (), INVALIDATE_CONTEXT);
/* Check if TH exists. Windows sometimes uses a non-existent
thread id in its events. */
return so;
}
-static char *
-get_image_name (HANDLE h, void *address, int unicode)
-{
-#ifdef __CYGWIN__
- static char buf[__PMAX];
-#else
- static char buf[(2 * __PMAX) + 1];
-#endif
- DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
- char *address_ptr;
- int len = 0;
- char b[2];
- SIZE_T done;
-
- /* Attempt to read the name of the dll that was detected.
- This is documented to work only when actively debugging
- a program. It will not work for attached processes. */
- if (address == NULL)
- return NULL;
-
- /* See if we could read the address of a string, and that the
- address isn't null. */
- if (!ReadProcessMemory (h, address, &address_ptr,
- sizeof (address_ptr), &done)
- || done != sizeof (address_ptr) || !address_ptr)
- return NULL;
-
- /* Find the length of the string. */
- while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
- && (b[0] != 0 || b[size - 1] != 0) && done == size)
- continue;
-
- if (!unicode)
- ReadProcessMemory (h, address_ptr, buf, len, &done);
- else
- {
- WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
- ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
- &done);
-#ifdef __CYGWIN__
- wcstombs (buf, unicode_address, __PMAX);
-#else
- WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
- 0, 0);
-#endif
- }
-
- return buf;
-}
-
-/* Handle a DLL load event, and return 1.
-
- This function assumes that this event did not occur during inferior
- initialization, where their event info may be incomplete (see
- do_initial_windows_stuff and windows_add_all_dlls for more info
- on how we handle DLL loading during that phase). */
+/* See nat/windows-nat.h. */
-static void
-handle_load_dll ()
+void
+windows_nat::handle_load_dll ()
{
LOAD_DLL_DEBUG_INFO *event = ¤t_event.u.LoadDll;
- char *dll_name;
+ 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,
xfree (so);
}
-/* Handle a DLL unload event.
- Return 1 if successful, or zero otherwise.
-
- This function assumes that this event did not occur during inferior
- initialization, where their event info may be incomplete (see
- do_initial_windows_stuff and windows_add_all_dlls for more info
- on how we handle DLL loading during that phase). */
+/* See nat/windows-nat.h. */
-static void
-handle_unload_dll ()
+void
+windows_nat::handle_unload_dll ()
{
LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
struct so_list *so;
CloseHandle ((HANDLE) event_id);
}
-/* Handle DEBUG_STRING output from child process.
- Cygwin prepends its messages with a "cygwin:". Interpret this as
- a Cygwin signal. Otherwise just print the string as a warning. */
-static int
-handle_output_debug_string (struct target_waitstatus *ourstatus)
+/* See nat/windows-nat.h. */
+
+int
+windows_nat::handle_output_debug_string (struct target_waitstatus *ourstatus)
{
gdb::unique_xmalloc_ptr<char> s;
int retval = 0;
static void
display_selectors (const char * args, int from_tty)
{
- if (!current_thread)
+ if (!current_windows_thread)
{
puts_filtered ("Impossible to display selectors now.\n");
return;
if (wow64_process)
{
puts_filtered ("Selector $cs\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegCs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegCs);
puts_filtered ("Selector $ds\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegDs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegDs);
puts_filtered ("Selector $es\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegEs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegEs);
puts_filtered ("Selector $ss\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegSs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegSs);
puts_filtered ("Selector $fs\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegFs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegFs);
puts_filtered ("Selector $gs\n");
- display_selector (current_thread->h,
- current_thread->wow64_context.SegGs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->wow64_context.SegGs);
}
else
#endif
{
puts_filtered ("Selector $cs\n");
- display_selector (current_thread->h,
- current_thread->context.SegCs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegCs);
puts_filtered ("Selector $ds\n");
- display_selector (current_thread->h,
- current_thread->context.SegDs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegDs);
puts_filtered ("Selector $es\n");
- display_selector (current_thread->h,
- current_thread->context.SegEs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegEs);
puts_filtered ("Selector $ss\n");
- display_selector (current_thread->h,
- current_thread->context.SegSs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegSs);
puts_filtered ("Selector $fs\n");
- display_selector (current_thread->h,
- current_thread->context.SegFs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegFs);
puts_filtered ("Selector $gs\n");
- display_selector (current_thread->h,
- current_thread->context.SegGs);
+ display_selector (current_windows_thread->h,
+ current_windows_thread->context.SegGs);
}
}
else
int sel;
sel = parse_and_eval_long (args);
printf_filtered ("Selector \"%s\"\n",args);
- display_selector (current_thread->h, sel);
+ display_selector (current_windows_thread->h, sel);
}
}
-#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
- printf_unfiltered ("gdb: Target exception %s at %s\n", x, \
- host_address_to_string (\
- current_event.u.Exception.ExceptionRecord.ExceptionAddress))
+/* See nat/windows-nat.h. */
-static handle_exception_result
-handle_exception (struct target_waitstatus *ourstatus)
+bool
+windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
{
- EXCEPTION_RECORD *rec = ¤t_event.u.Exception.ExceptionRecord;
- DWORD code = rec->ExceptionCode;
- handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
-
- memcpy (&siginfo_er, rec, sizeof siginfo_er);
-
- ourstatus->kind = TARGET_WAITKIND_STOPPED;
-
- /* Record the context of the current thread. */
- thread_rec (current_event.dwThreadId, DONT_SUSPEND);
-
- switch (code)
+ if (rec->NumberParameters >= 3
+ && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
{
- case EXCEPTION_ACCESS_VIOLATION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
-#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 HANDLE_EXCEPTION_UNHANDLED;
- }
-#endif
- break;
- case STATUS_STACK_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_SEGV;
- break;
- case STATUS_FLOAT_DENORMAL_OPERAND:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INEXACT_RESULT:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_INVALID_OPERATION:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_STACK_CHECK:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_UNDERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_FLOAT_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_DIVIDE_BY_ZERO:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case STATUS_INTEGER_OVERFLOW:
- DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
- ourstatus->value.sig = GDB_SIGNAL_FPE;
- break;
- case EXCEPTION_BREAKPOINT:
-#ifdef __x86_64__
- if (ignore_first_breakpoint)
- {
- /* For WOW64 processes, there are always 2 breakpoint exceptions
- on startup, first a BREAKPOINT for the 64bit ntdll.dll,
- then a WX86_BREAKPOINT for the 32bit ntdll.dll.
- Here we only care about the WX86_BREAKPOINT's. */
- ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
- ignore_first_breakpoint = false;
- }
-#endif
- /* FALLTHROUGH */
- case STATUS_WX86_BREAKPOINT:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case DBG_CONTROL_C:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case DBG_CONTROL_BREAK:
- DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
- ourstatus->value.sig = GDB_SIGNAL_INT;
- break;
- case EXCEPTION_SINGLE_STEP:
- case STATUS_WX86_SINGLE_STEP:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
- ourstatus->value.sig = GDB_SIGNAL_TRAP;
- break;
- case EXCEPTION_ILLEGAL_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_PRIV_INSTRUCTION:
- DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
- ourstatus->value.sig = GDB_SIGNAL_ILL;
- break;
- case EXCEPTION_NONCONTINUABLE_EXCEPTION:
- 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;
+ 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]);
- 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;
- 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;
- named_thread = thread_rec (named_thread_id, DONT_INVALIDATE_CONTEXT);
- if (named_thread != NULL)
+ thread_name_len = target_read_string (thread_name_target,
+ &thread_name, 1025, NULL);
+ if (thread_name_len > 0)
{
- 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);
- }
+ thread_name.get ()[thread_name_len - 1] = '\0';
+ named_thread->name = std::move (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 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 (
- current_event.u.Exception.ExceptionRecord.ExceptionAddress));
- ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
- break;
+
+ return true;
}
- exception_count++;
- last_sig = ourstatus->value.sig;
- return result;
+
+ return false;
}
/* Resume thread specified by ID, or all artificially suspended
desired_stop_thread_id = id;
- /* If there are pending stops, and we might plausibly hit one of
- them, we don't want to actually continue the inferior -- we just
- want to report the stop. In this case, we just pretend to
- continue. See the comment by the definition of "pending_stops"
- for details on why this is needed. */
- for (const auto &item : pending_stops)
- {
- if (desired_stop_thread_id == -1
- || desired_stop_thread_id == item.thread_id)
- {
- DEBUG_EVENTS (("windows_continue - pending stop anticipated, "
- "desired=0x%x, item=0x%x\n",
- desired_stop_thread_id, item.thread_id));
- return TRUE;
- }
- }
-
- DEBUG_EVENTS (("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s);\n",
- (unsigned) last_wait_event.dwProcessId,
- (unsigned) last_wait_event.dwThreadId,
- continue_status == DBG_CONTINUE ?
- "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
+ if (matching_pending_stop (debug_events))
+ return TRUE;
for (windows_thread_info *th : thread_list)
if (id == -1 || id == (int) th->tid)
th->suspend ();
}
- res = ContinueDebugEvent (last_wait_event.dwProcessId,
- last_wait_event.dwThreadId,
- continue_status);
+ res = continue_last_debug_event (continue_status, debug_events);
if (!res)
error (_("Failed to resume program execution"
(unsigned) GetLastError ());
/* We can not debug anything in that case. */
}
- current_thread
+ current_windows_thread
= windows_add_thread (ptid_t (current_event.dwProcessId,
current_event.dwThreadId, 0),
current_event.u.CreateThread.hThread,
ptid.pid (), (unsigned) ptid.lwp (), step, sig));
/* Get context for currently selected thread. */
- th = thread_rec (inferior_ptid.lwp (), DONT_INVALIDATE_CONTEXT);
+ th = thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
if (th)
{
#ifdef __x86_64__
current_event = iter->event;
inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- current_thread = thread_rec (thread_id, INVALIDATE_CONTEXT);
- current_thread->reload_context = 1;
+ current_windows_thread = thread_rec (inferior_ptid,
+ INVALIDATE_CONTEXT);
+ current_windows_thread->reload_context = 1;
DEBUG_EVENTS (("get_windows_debug_event - "
"pending stop found in 0x%x (desired=0x%x)\n",
if (!(debug_event = wait_for_debug_event (¤t_event, 1000)))
goto out;
- event_count++;
continue_status = DBG_CONTINUE;
event_code = current_event.dwDebugEventCode;
"EXCEPTION_DEBUG_EVENT"));
if (saw_create != 1)
break;
- switch (handle_exception (ourstatus))
+ switch (handle_exception (ourstatus, debug_exceptions))
{
case HANDLE_EXCEPTION_UNHANDLED:
default:
== EXCEPTION_BREAKPOINT)
&& windows_initialization_done)
{
- th = thread_rec (thread_id, INVALIDATE_CONTEXT);
+ ptid_t ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
+ th = thread_rec (ptid, INVALIDATE_CONTEXT);
th->stopped_at_software_breakpoint = true;
}
pending_stops.push_back ({thread_id, *ourstatus, current_event});
else
{
inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- current_thread = th;
- if (!current_thread)
- current_thread = thread_rec (thread_id, INVALIDATE_CONTEXT);
+ current_windows_thread = th;
+ if (!current_windows_thread)
+ current_windows_thread = thread_rec (inferior_ptid,
+ INVALIDATE_CONTEXT);
}
out:
{
ptid_t result = ptid_t (current_event.dwProcessId, retval, 0);
- if (current_thread != nullptr)
+ if (current_windows_thread != nullptr)
{
- current_thread->stopped_at_software_breakpoint = false;
+ 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_thread->stopped_at_software_breakpoint = true;
+ current_windows_thread->stopped_at_software_breakpoint = true;
}
return result;
struct inferior *inf;
last_sig = GDB_SIGNAL_0;
- event_count = 0;
- exception_count = 0;
open_process_used = 0;
debug_registers_changed = 0;
debug_registers_used = 0;
{
windows_thread_info *th;
- th = thread_rec (ptid.lwp (), DONT_INVALIDATE_CONTEXT);
+ th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
if (th == NULL)
return false;
const char *
windows_nat_target::thread_name (struct thread_info *thr)
{
- return thread_rec (thr->ptid.lwp (), DONT_INVALIDATE_CONTEXT)->name.get ();
+ return thread_rec (thr->ptid, DONT_INVALIDATE_CONTEXT)->name.get ();
}
bool
windows_nat_target::thread_alive (ptid_t ptid)
{
- int tid;
-
gdb_assert (ptid.lwp () != 0);
- tid = ptid.lwp ();
- return (WaitForSingleObject (thread_rec (tid, DONT_INVALIDATE_CONTEXT)->h, 0)
+ return (WaitForSingleObject (thread_rec (ptid, DONT_INVALIDATE_CONTEXT)->h, 0)
!= WAIT_OBJECT_0);
}