#include "nat/windows-nat.h"
#include "gdbsupport/common-debug.h"
-#define STATUS_WX86_BREAKPOINT 0x4000001F
-#define STATUS_WX86_SINGLE_STEP 0x4000001E
-
namespace windows_nat
{
DWORD main_thread_id;
enum gdb_signal last_sig = GDB_SIGNAL_0;
DEBUG_EVENT current_event;
-DEBUG_EVENT last_wait_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;
+
windows_thread_info *current_windows_thread;
DWORD desired_stop_thread_id = -1;
std::vector<pending_stop> pending_stops;
EXCEPTION_RECORD siginfo_er;
+#ifdef __x86_64__
+bool ignore_first_breakpoint = false;
+#endif
+
/* Note that 'debug_events' must be locally defined in the relevant
functions. */
#define DEBUG_EVENTS(x) if (debug_events) debug_printf x
windows_thread_info::~windows_thread_info ()
{
- CloseHandle (h);
}
void
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
+ if (handle_access_violation (rec))
+ return HANDLE_EXCEPTION_UNHANDLED;
break;
case STATUS_STACK_OVERFLOW:
DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
/* See nat/windows-nat.h. */
+gdb::optional<pending_stop>
+fetch_pending_stop (bool debug_events)
+{
+ gdb::optional<pending_stop> result;
+ for (auto iter = pending_stops.begin ();
+ iter != pending_stops.end ();
+ ++iter)
+ {
+ if (desired_stop_thread_id == -1
+ || desired_stop_thread_id == iter->thread_id)
+ {
+ result = *iter;
+ current_event = iter->event;
+
+ DEBUG_EVENTS (("get_windows_debug_event - "
+ "pending stop found in 0x%x (desired=0x%x)\n",
+ iter->thread_id, desired_stop_thread_id));
+
+ pending_stops.erase (iter);
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* See nat/windows-nat.h. */
+
BOOL
continue_last_debug_event (DWORD continue_status, bool debug_events)
{
continue_status);
}
+/* See nat/windows-nat.h. */
+
+BOOL
+wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
+{
+ BOOL result = WaitForDebugEvent (event, timeout);
+ if (result)
+ last_wait_event = *event;
+ return result;
+}
}