Share some Windows-related globals

This moves some Windows-related globals into nat/windows-nat.c,
sharing them between gdb and gdbserver.

gdb/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* windows-nat.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(struct pending_stop, siginfo_er): Move to nat/windows-nat.c.
	(display_selectors, fake_create_process)
	(get_windows_debug_event): Update.
	* nat/windows-nat.h (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(struct pending_stop, siginfo_er): Move from windows-nat.c.
	* nat/windows-nat.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, last_wait_event)
	(current_windows_thread, desired_stop_thread_id, pending_stops)
	(siginfo_er): New globals.  Move from windows-nat.c.

gdbserver/ChangeLog
2020-04-08  Tom Tromey  <tromey@adacore.com>

	* win32-low.c (current_process_handle, current_process_id)
	(main_thread_id, last_sig, current_event, siginfo_er): Move to
	nat/windows-nat.c.
This commit is contained in:
Tom Tromey 2020-04-08 14:33:35 -06:00
parent 9d8679cc71
commit 3c76026df8
6 changed files with 130 additions and 96 deletions

View file

@ -1,3 +1,20 @@
2020-04-08 Tom Tromey <tromey@adacore.com>
* windows-nat.c (current_process_handle, current_process_id)
(main_thread_id, last_sig, current_event, last_wait_event)
(current_windows_thread, desired_stop_thread_id, pending_stops)
(struct pending_stop, siginfo_er): Move to nat/windows-nat.c.
(display_selectors, fake_create_process)
(get_windows_debug_event): Update.
* nat/windows-nat.h (current_process_handle, current_process_id)
(main_thread_id, last_sig, current_event, last_wait_event)
(current_windows_thread, desired_stop_thread_id, pending_stops)
(struct pending_stop, siginfo_er): Move from windows-nat.c.
* nat/windows-nat.c (current_process_handle, current_process_id)
(main_thread_id, last_sig, current_event, last_wait_event)
(current_windows_thread, desired_stop_thread_id, pending_stops)
(siginfo_er): New globals. Move from windows-nat.c.
2020-04-08 Tom Tromey <tromey@adacore.com> 2020-04-08 Tom Tromey <tromey@adacore.com>
* windows-nat.c (get_image_name): Move to nat/windows-nat.c. * windows-nat.c (get_image_name): Move to nat/windows-nat.c.

View file

@ -1,5 +1,5 @@
/* Internal interfaces for the Windows code /* Internal interfaces for the Windows code
Copyright (C) 1995-2019 Free Software Foundation, Inc. Copyright (C) 1995-2020 Free Software Foundation, Inc.
This file is part of GDB. This file is part of GDB.
@ -22,6 +22,17 @@
namespace windows_nat namespace windows_nat
{ {
HANDLE current_process_handle;
DWORD current_process_id;
DWORD main_thread_id;
enum gdb_signal last_sig = GDB_SIGNAL_0;
DEBUG_EVENT current_event;
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;
windows_thread_info::~windows_thread_info () windows_thread_info::~windows_thread_info ()
{ {
CloseHandle (h); CloseHandle (h);

View file

@ -20,6 +20,9 @@
#define NAT_WINDOWS_NAT_H #define NAT_WINDOWS_NAT_H
#include <windows.h> #include <windows.h>
#include <vector>
#include "target/waitstatus.h"
namespace windows_nat namespace windows_nat
{ {
@ -111,6 +114,60 @@ enum thread_disposition_type
extern windows_thread_info *thread_rec (ptid_t ptid, extern windows_thread_info *thread_rec (ptid_t ptid,
thread_disposition_type disposition); thread_disposition_type disposition);
/* Currently executing process */
extern HANDLE current_process_handle;
extern DWORD current_process_id;
extern DWORD main_thread_id;
extern enum gdb_signal last_sig;
/* The current debug event from WaitForDebugEvent or from a pending
stop. */
extern 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. */
extern DEBUG_EVENT last_wait_event;
/* Info on currently selected thread */
extern windows_thread_info *current_windows_thread;
/* 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. */
extern DWORD desired_stop_thread_id;
/* 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. */
extern std::vector<pending_stop> pending_stops;
/* Contents of $_siginfo */
extern EXCEPTION_RECORD siginfo_er;
/* Return the name of the DLL referenced by H at ADDRESS. UNICODE /* Return the name of the DLL referenced by H at ADDRESS. UNICODE
determines what sort of string is read from the inferior. Returns determines what sort of string is read from the inferior. Returns
the name of the DLL, or NULL on error. If a name is returned, it the name of the DLL, or NULL on error. If a name is returned, it

View file

@ -244,28 +244,8 @@ static CORE_ADDR cygwin_get_dr (int i);
static unsigned long cygwin_get_dr6 (void); static unsigned long cygwin_get_dr6 (void);
static unsigned long cygwin_get_dr7 (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; 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. */ /* Counts of things. */
static int exception_count = 0; static int exception_count = 0;
static int event_count = 0; static int event_count = 0;
@ -336,37 +316,6 @@ static const struct xlate_exception xlate[] =
#endif /* 0 */ #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> struct windows_nat_target final : public x86_nat_target<inf_child_target>
{ {
void close () override; void close () override;
@ -387,7 +336,7 @@ struct windows_nat_target final : public x86_nat_target<inf_child_target>
bool stopped_by_sw_breakpoint () 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 bool supports_stopped_by_sw_breakpoint () override
@ -1207,7 +1156,7 @@ display_selector (HANDLE thread, DWORD sel)
static void static void
display_selectors (const char * args, int from_tty) display_selectors (const char * args, int from_tty)
{ {
if (!current_thread) if (!current_windows_thread)
{ {
puts_filtered ("Impossible to display selectors now.\n"); puts_filtered ("Impossible to display selectors now.\n");
return; return;
@ -1218,45 +1167,45 @@ display_selectors (const char * args, int from_tty)
if (wow64_process) if (wow64_process)
{ {
puts_filtered ("Selector $cs\n"); puts_filtered ("Selector $cs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegCs); current_windows_thread->wow64_context.SegCs);
puts_filtered ("Selector $ds\n"); puts_filtered ("Selector $ds\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegDs); current_windows_thread->wow64_context.SegDs);
puts_filtered ("Selector $es\n"); puts_filtered ("Selector $es\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegEs); current_windows_thread->wow64_context.SegEs);
puts_filtered ("Selector $ss\n"); puts_filtered ("Selector $ss\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegSs); current_windows_thread->wow64_context.SegSs);
puts_filtered ("Selector $fs\n"); puts_filtered ("Selector $fs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegFs); current_windows_thread->wow64_context.SegFs);
puts_filtered ("Selector $gs\n"); puts_filtered ("Selector $gs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->wow64_context.SegGs); current_windows_thread->wow64_context.SegGs);
} }
else else
#endif #endif
{ {
puts_filtered ("Selector $cs\n"); puts_filtered ("Selector $cs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegCs); current_windows_thread->context.SegCs);
puts_filtered ("Selector $ds\n"); puts_filtered ("Selector $ds\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegDs); current_windows_thread->context.SegDs);
puts_filtered ("Selector $es\n"); puts_filtered ("Selector $es\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegEs); current_windows_thread->context.SegEs);
puts_filtered ("Selector $ss\n"); puts_filtered ("Selector $ss\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegSs); current_windows_thread->context.SegSs);
puts_filtered ("Selector $fs\n"); puts_filtered ("Selector $fs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegFs); current_windows_thread->context.SegFs);
puts_filtered ("Selector $gs\n"); puts_filtered ("Selector $gs\n");
display_selector (current_thread->h, display_selector (current_windows_thread->h,
current_thread->context.SegGs); current_windows_thread->context.SegGs);
} }
} }
else else
@ -1264,7 +1213,7 @@ display_selectors (const char * args, int from_tty)
int sel; int sel;
sel = parse_and_eval_long (args); sel = parse_and_eval_long (args);
printf_filtered ("Selector \"%s\"\n",args); printf_filtered ("Selector \"%s\"\n",args);
display_selector (current_thread->h, sel); display_selector (current_windows_thread->h, sel);
} }
} }
@ -1587,7 +1536,7 @@ fake_create_process (void)
(unsigned) GetLastError ()); (unsigned) GetLastError ());
/* We can not debug anything in that case. */ /* We can not debug anything in that case. */
} }
current_thread current_windows_thread
= windows_add_thread (ptid_t (current_event.dwProcessId, = windows_add_thread (ptid_t (current_event.dwProcessId,
current_event.dwThreadId, 0), current_event.dwThreadId, 0),
current_event.u.CreateThread.hThread, current_event.u.CreateThread.hThread,
@ -1782,8 +1731,9 @@ windows_nat_target::get_windows_debug_event (int pid,
current_event = iter->event; current_event = iter->event;
inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0); inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
current_thread = thread_rec (inferior_ptid, INVALIDATE_CONTEXT); current_windows_thread = thread_rec (inferior_ptid,
current_thread->reload_context = 1; INVALIDATE_CONTEXT);
current_windows_thread->reload_context = 1;
DEBUG_EVENTS (("get_windows_debug_event - " DEBUG_EVENTS (("get_windows_debug_event - "
"pending stop found in 0x%x (desired=0x%x)\n", "pending stop found in 0x%x (desired=0x%x)\n",
@ -2006,9 +1956,10 @@ windows_nat_target::get_windows_debug_event (int pid,
else else
{ {
inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0); inferior_ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
current_thread = th; current_windows_thread = th;
if (!current_thread) if (!current_windows_thread)
current_thread = thread_rec (inferior_ptid, INVALIDATE_CONTEXT); current_windows_thread = thread_rec (inferior_ptid,
INVALIDATE_CONTEXT);
} }
out: out:
@ -2066,14 +2017,14 @@ windows_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
{ {
ptid_t result = ptid_t (current_event.dwProcessId, retval, 0); 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 if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
&& (current_event.u.Exception.ExceptionRecord.ExceptionCode && (current_event.u.Exception.ExceptionRecord.ExceptionCode
== EXCEPTION_BREAKPOINT) == EXCEPTION_BREAKPOINT)
&& windows_initialization_done) && windows_initialization_done)
current_thread->stopped_at_software_breakpoint = true; current_windows_thread->stopped_at_software_breakpoint = true;
} }
return result; return result;

View file

@ -1,3 +1,9 @@
2020-04-08 Tom Tromey <tromey@adacore.com>
* win32-low.c (current_process_handle, current_process_id)
(main_thread_id, last_sig, current_event, siginfo_er): Move to
nat/windows-nat.c.
2020-04-08 Tom Tromey <tromey@adacore.com> 2020-04-08 Tom Tromey <tromey@adacore.com>
* win32-low.c (get_image_name): Remove. * win32-low.c (get_image_name): Remove.

View file

@ -74,14 +74,6 @@ int using_threads = 1;
/* Globals. */ /* Globals. */
static int attaching = 0; static int attaching = 0;
static HANDLE current_process_handle = NULL;
static DWORD current_process_id = 0;
static DWORD main_thread_id = 0;
static EXCEPTION_RECORD siginfo_er; /* Contents of $_siginfo */
static enum gdb_signal last_sig = GDB_SIGNAL_0;
/* The current debug event from WaitForDebugEvent. */
static DEBUG_EVENT current_event;
/* A status that hasn't been reported to the core yet, and so /* A status that hasn't been reported to the core yet, and so
win32_wait should return it next, instead of fetching the next win32_wait should return it next, instead of fetching the next