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;
-
/* 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
ContinueDebugEvent. */
static DEBUG_EVENT last_wait_event;
-DWORD desired_stop_thread_id = -1;
-std::vector<pending_stop> pending_stops;
-EXCEPTION_RECORD siginfo_er;
-
-#ifdef __x86_64__
-bool wow64_process = false;
-bool ignore_first_breakpoint = false;
-#endif
-
AdjustTokenPrivileges_ftype *AdjustTokenPrivileges;
DebugActiveProcessStop_ftype *DebugActiveProcessStop;
DebugBreakProcess_ftype *DebugBreakProcess;
#define MS_VC_EXCEPTION 0x406d1388
handle_exception_result
-handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
+windows_process_info::handle_exception (struct target_waitstatus *ourstatus,
+ bool debug_exceptions)
{
#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
debug_printf ("gdb: Target exception %s at %s\n", x, \
#undef DEBUG_EXCEPTION_SIMPLE
}
-/* Iterate over all DLLs currently mapped by our inferior, looking for
- a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
- list of solibs; otherwise do nothing. LOAD_ADDR NULL means add all
- DLLs to the list of solibs; this is used when the inferior finishes
- its initialization, and all the DLLs it statically depends on are
- presumed loaded. */
+/* See nat/windows-nat.h. */
-static void
-windows_add_dll (LPVOID load_addr)
+void
+windows_process_info::add_dll (LPVOID load_addr)
{
HMODULE dummy_hmodule;
DWORD cb_needed;
#ifdef __x86_64__
if (wow64_process)
{
- if (EnumProcessModulesEx (current_process_handle, &dummy_hmodule,
+ if (EnumProcessModulesEx (handle, &dummy_hmodule,
sizeof (HMODULE), &cb_needed,
LIST_MODULES_32BIT) == 0)
return;
else
#endif
{
- if (EnumProcessModules (current_process_handle, &dummy_hmodule,
+ if (EnumProcessModules (handle, &dummy_hmodule,
sizeof (HMODULE), &cb_needed) == 0)
return;
}
#ifdef __x86_64__
if (wow64_process)
{
- if (EnumProcessModulesEx (current_process_handle, hmodules,
+ if (EnumProcessModulesEx (handle, hmodules,
cb_needed, &cb_needed,
LIST_MODULES_32BIT) == 0)
return;
else
#endif
{
- if (EnumProcessModules (current_process_handle, hmodules,
+ if (EnumProcessModules (handle, hmodules,
cb_needed, &cb_needed) == 0)
return;
}
char dll_name[MAX_PATH];
#endif
const char *name;
- if (GetModuleInformation (current_process_handle, hmodules[i],
+ if (GetModuleInformation (handle, hmodules[i],
&mi, sizeof (mi)) == 0)
continue;
- if (GetModuleFileNameEx (current_process_handle, hmodules[i],
+ if (GetModuleFileNameEx (handle, hmodules[i],
dll_name, sizeof (dll_name)) == 0)
continue;
#ifdef __USEWIDE
/* See nat/windows-nat.h. */
void
-dll_loaded_event ()
+windows_process_info::dll_loaded_event ()
{
gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);
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);
+ dll_name = get_image_name (handle, event->lpImageName, event->fUnicode);
/* If the DLL name could not be gleaned via lpImageName, try harder
by enumerating all the DLLs loaded into the inferior, looking for
one that is loaded at base address = lpBaseOfDll. */
if (dll_name != nullptr)
handle_load_dll (dll_name, event->lpBaseOfDll);
else if (event->lpBaseOfDll != nullptr)
- windows_add_dll (event->lpBaseOfDll);
+ add_dll (event->lpBaseOfDll);
}
/* See nat/windows-nat.h. */
void
-windows_add_all_dlls ()
+windows_process_info::add_all_dlls ()
{
- windows_add_dll (nullptr);
+ add_dll (nullptr);
}
/* See nat/windows-nat.h. */
bool
-matching_pending_stop (bool debug_events)
+windows_process_info::matching_pending_stop (bool debug_events)
{
/* If there are pending stops, and we might plausibly hit one of
them, we don't want to actually continue the inferior -- we just
/* See nat/windows-nat.h. */
gdb::optional<pending_stop>
-fetch_pending_stop (bool debug_events)
+windows_process_info::fetch_pending_stop (bool debug_events)
{
gdb::optional<pending_stop> result;
for (auto iter = pending_stops.begin ();
INVALIDATE_CONTEXT
};
-/* Find a thread record given a thread id. THREAD_DISPOSITION
- controls whether the thread is suspended, and whether the context
- is invalidated.
+/* A single pending stop. See "pending_stops" for more
+ information. */
+struct pending_stop
+{
+ /* The thread id. */
+ DWORD thread_id;
- This function must be supplied by the embedding application. */
-extern windows_thread_info *thread_rec (ptid_t ptid,
- thread_disposition_type disposition);
+ /* 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;
+};
-/* Handle OUTPUT_DEBUG_STRING_EVENT from child process. Updates
- OURSTATUS and returns the thread id if this represents a thread
- change (this is specific to Cygwin), otherwise 0.
+typedef enum
+{
+ HANDLE_EXCEPTION_UNHANDLED = 0,
+ HANDLE_EXCEPTION_HANDLED,
+ HANDLE_EXCEPTION_IGNORED
+} handle_exception_result;
- Cygwin prepends its messages with a "cygwin:". Interpret this as
- a Cygwin signal. Otherwise just print the string as a warning.
+/* A single Windows process. An object of this type (or subclass) is
+ created by the client. Some methods must be provided by the client
+ as well. */
- This function must be supplied by the embedding application. */
-extern int handle_output_debug_string (struct target_waitstatus *ourstatus);
+struct windows_process_info
+{
+ /* The process handle */
+ HANDLE handle = 0;
+ DWORD id = 0;
+ DWORD main_thread_id = 0;
+ enum gdb_signal last_sig = GDB_SIGNAL_0;
+
+ /* The current debug event from WaitForDebugEvent or from a pending
+ stop. */
+ DEBUG_EVENT current_event {};
+
+ /* 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. */
+ DWORD desired_stop_thread_id = -1;
+
+ /* 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. */
+ std::vector<pending_stop> pending_stops;
+
+ /* Contents of $_siginfo */
+ EXCEPTION_RECORD siginfo_er {};
-/* Handle a DLL load event.
+#ifdef __x86_64__
+ /* The target is a WOW64 process */
+ bool wow64_process = false;
+ /* Ignore first breakpoint exception of WOW64 process */
+ bool ignore_first_breakpoint = false;
+#endif
- This function assumes that the current event did not occur during
- inferior initialization.
- DLL_NAME is the name of the library. BASE is the base load
- address.
+ /* Find a thread record given a thread id. THREAD_DISPOSITION
+ controls whether the thread is suspended, and whether the context
+ is invalidated.
- This function must be supplied by the embedding application. */
+ This function must be supplied by the embedding application. */
+ windows_thread_info *thread_rec (ptid_t ptid,
+ thread_disposition_type disposition);
-extern void handle_load_dll (const char *dll_name, LPVOID base);
+ /* Handle OUTPUT_DEBUG_STRING_EVENT from child process. Updates
+ OURSTATUS and returns the thread id if this represents a thread
+ change (this is specific to Cygwin), otherwise 0.
-/* Handle a DLL unload event.
+ Cygwin prepends its messages with a "cygwin:". Interpret this as
+ a Cygwin signal. Otherwise just print the string as a warning.
- This function assumes that this event did not occur during inferior
- initialization.
+ This function must be supplied by the embedding application. */
+ int handle_output_debug_string (struct target_waitstatus *ourstatus);
- This function must be supplied by the embedding application. */
+ /* Handle a DLL load event.
-extern void handle_unload_dll ();
+ This function assumes that the current event did not occur during
+ inferior initialization.
-/* Handle MS_VC_EXCEPTION when processing a stop. MS_VC_EXCEPTION is
- somewhat undocumented but is used to tell the debugger the name of
- a thread.
+ DLL_NAME is the name of the library. BASE is the base load
+ address.
- Return true if the exception was handled; return false otherwise.
+ This function must be supplied by the embedding application. */
- This function must be supplied by the embedding application. */
+ void handle_load_dll (const char *dll_name, LPVOID base);
-extern bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
+ /* Handle a DLL unload event.
-/* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
- application a chance to change it to be considered "unhandled".
- This function must be supplied by the embedding application. If it
- returns true, then the exception is "unhandled". */
+ This function assumes that this event did not occur during inferior
+ initialization.
-extern bool handle_access_violation (const EXCEPTION_RECORD *rec);
+ This function must be supplied by the embedding application. */
+ void handle_unload_dll ();
-/* Currently executing process */
-extern HANDLE current_process_handle;
-extern DWORD current_process_id;
-extern DWORD main_thread_id;
-extern enum gdb_signal last_sig;
+ /* Handle MS_VC_EXCEPTION when processing a stop. MS_VC_EXCEPTION is
+ somewhat undocumented but is used to tell the debugger the name of
+ a thread.
-/* The current debug event from WaitForDebugEvent or from a pending
- stop. */
-extern DEBUG_EVENT current_event;
+ Return true if the exception was handled; return false otherwise.
-/* 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;
+ This function must be supplied by the embedding application. */
-/* A single pending stop. See "pending_stops" for more
- information. */
-struct pending_stop
-{
- /* The thread id. */
- DWORD thread_id;
+ bool handle_ms_vc_exception (const EXCEPTION_RECORD *rec);
- /* 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;
-};
+ /* When EXCEPTION_ACCESS_VIOLATION is processed, we give the embedding
+ application a chance to change it to be considered "unhandled".
+ This function must be supplied by the embedding application. If it
+ returns true, then the exception is "unhandled". */
-/* 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;
+ bool handle_access_violation (const EXCEPTION_RECORD *rec);
-/* Contents of $_siginfo */
-extern EXCEPTION_RECORD siginfo_er;
+ handle_exception_result handle_exception
+ (struct target_waitstatus *ourstatus, bool debug_exceptions);
-#ifdef __x86_64__
-/* The target is a WOW64 process */
-extern bool wow64_process;
-/* Ignore first breakpoint exception of WOW64 process */
-extern bool ignore_first_breakpoint;
-#endif
+ /* Call to indicate that a DLL was loaded. */
-typedef enum
-{
- HANDLE_EXCEPTION_UNHANDLED = 0,
- HANDLE_EXCEPTION_HANDLED,
- HANDLE_EXCEPTION_IGNORED
-} handle_exception_result;
+ void dll_loaded_event ();
-extern handle_exception_result handle_exception
- (struct target_waitstatus *ourstatus, bool debug_exceptions);
+ /* Iterate over all DLLs currently mapped by our inferior, and
+ add them to our list of solibs. */
-/* Call to indicate that a DLL was loaded. */
+ void add_all_dlls ();
-extern void dll_loaded_event ();
+ /* Return true if there is a pending stop matching
+ desired_stop_thread_id. If DEBUG_EVENTS is true, logging will be
+ enabled. */
-/* Iterate over all DLLs currently mapped by our inferior, and
- add them to our list of solibs. */
+ bool matching_pending_stop (bool debug_events);
-extern void windows_add_all_dlls ();
+ /* See if a pending stop matches DESIRED_STOP_THREAD_ID. If so,
+ remove it from the list of pending stops, set 'current_event', and
+ return it. Otherwise, return an empty optional. */
-/* Return true if there is a pending stop matching
- desired_stop_thread_id. If DEBUG_EVENTS is true, logging will be
- enabled. */
+ gdb::optional<pending_stop> fetch_pending_stop (bool debug_events);
-extern bool matching_pending_stop (bool debug_events);
+private:
-/* See if a pending stop matches DESIRED_STOP_THREAD_ID. If so,
- remove it from the list of pending stops, set 'current_event', and
- return it. Otherwise, return an empty optional. */
+ /* Iterate over all DLLs currently mapped by our inferior, looking for
+ a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
+ list of solibs; otherwise do nothing. LOAD_ADDR NULL means add all
+ DLLs to the list of solibs; this is used when the inferior finishes
+ its initialization, and all the DLLs it statically depends on are
+ presumed loaded. */
-extern gdb::optional<pending_stop> fetch_pending_stop (bool debug_events);
+ void add_dll (LPVOID load_addr);
+};
/* A simple wrapper for ContinueDebugEvent that continues the last
waited-for event. If DEBUG_EVENTS is true, logging will be
using namespace windows_nat;
+/* The current process. */
+static windows_process_info windows_process;
+
#undef STARTUPINFO
#undef CreateProcess
#undef GetModuleFileNameEx
bool stopped_by_sw_breakpoint () override
{
windows_thread_info *th
- = thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
+ = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
return th->stopped_at_software_breakpoint;
}
/* 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 (auto &th : thread_list)
if (th->tid == ptid.lwp ())
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);
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::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));
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. */
/* See nat/windows-nat.h. */
void
-windows_nat::handle_load_dll (const char *dll_name, LPVOID base)
+windows_nat::windows_process_info::handle_load_dll (const char *dll_name,
+ LPVOID base)
{
windows_solib *solib = windows_make_so (dll_name, base);
DEBUG_EVENTS ("Loading dll \"%s\" at %s.", solib->name.c_str (),
/* 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;
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)
/* 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)
{
int retval = 0;
LDT_ENTRY info;
BOOL ret;
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
ret = Wow64GetThreadSelectorEntry (thread, sel, &info);
else
#endif
}
windows_thread_info *current_windows_thread
- = thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
+ = windows_process.thread_rec (inferior_ptid, DONT_INVALIDATE_CONTEXT);
if (!args)
{
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
gdb_puts ("Selector $cs\n");
display_selector (current_windows_thread->h,
/* See nat/windows-nat.h. */
bool
-windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+windows_nat::windows_process_info::handle_ms_vc_exception
+ (const EXCEPTION_RECORD *rec)
{
if (rec->NumberParameters >= 3
&& (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
/* See nat/windows-nat.h. */
bool
-windows_nat::handle_access_violation (const EXCEPTION_RECORD *rec)
+windows_nat::windows_process_info::handle_access_violation
+ (const EXCEPTION_RECORD *rec)
{
#ifdef __CYGWIN__
/* See if the access violation happened within the cygwin DLL
{
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 (auto &th : thread_list)
if (id == -1 || id == (int) th->tid)
{
#ifdef __x86_64__
- if (wow64_process)
+ if (windows_process.wow64_process)
{
if (th->debug_registers_changed)
{
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. */
}
- windows_add_thread (ptid_t (current_event.dwProcessId, 0,
- current_event.dwThreadId),
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase,
+ 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 current_event.dwThreadId;
+ 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.", sig);
}
- else if (sig == last_sig)
+ else if (sig == windows_process.last_sig)
continue_status = DBG_EXCEPTION_NOT_HANDLED;
else
#if 0
}
#endif
DEBUG_EXCEPT ("Can only continue with received signal %d.",
- last_sig);
+ windows_process.last_sig);
}
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
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)
{
return TRUE;
#ifdef __x86_64__
- if (wow64_process)
+ 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
if (wow64_dbgbreak != nullptr)
{
- HANDLE thread = CreateRemoteThread (current_process_handle, NULL,
+ HANDLE thread = CreateRemoteThread (windows_process.handle, NULL,
0, (LPTHREAD_START_ROUTINE)
wow64_dbgbreak, NULL, 0, NULL);
if (thread)
else
#endif
{
- if (!DebugBreakProcess (current_process_handle))
+ if (!DebugBreakProcess (windows_process.handle))
warning (_("Could not interrupt program. "
"Press Ctrl-c in the program console."));
}
/* 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. */
- gdb::optional<pending_stop> stop = fetch_pending_stop (debug_events);
+ gdb::optional<pending_stop> stop
+ = windows_process.fetch_pending_stop (debug_events);
if (stop.has_value ())
{
thread_id = stop->thread_id;
*ourstatus = stop->status;
- ptid_t ptid (current_event.dwProcessId, thread_id);
- windows_thread_info *th = thread_rec (ptid, INVALIDATE_CONTEXT);
+ 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;
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;
+ event_code = windows_process.current_event.dwDebugEventCode;
ourstatus->set_spurious ();
have_saved_context = 0;
{
case CREATE_THREAD_DEBUG_EVENT:
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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;
+ 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,
+ (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 ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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,
+ windows_delete_thread (ptid_t (current_event->dwProcessId,
+ current_event->dwThreadId, 0),
+ current_event->u.ExitThread.dwExitCode,
false /* main_thread_p */);
break;
case CREATE_PROCESS_DEBUG_EVENT:
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
"CREATE_PROCESS_DEBUG_EVENT");
- CloseHandle (current_event.u.CreateProcessInfo.hFile);
+ 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. */
windows_add_thread
- (ptid_t (current_event.dwProcessId,
- current_event.dwThreadId, 0),
- current_event.u.CreateProcessInfo.hThread,
- current_event.u.CreateProcessInfo.lpThreadLocalBase,
+ (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 ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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
else
ourstatus->set_signalled (gdb_signal_from_host (exit_signal));
- thread_id = current_event.dwThreadId;
+ thread_id = current_event->dwThreadId;
}
break;
case LOAD_DLL_DEBUG_EVENT:
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
"LOAD_DLL_DEBUG_EVENT");
- CloseHandle (current_event.u.LoadDll.hFile);
+ CloseHandle (current_event->u.LoadDll.hFile);
if (saw_create != 1 || ! windows_initialization_done)
break;
- catch_errors (dll_loaded_event);
+ try
+ {
+ windows_process.dll_loaded_event ();
+ }
+ catch (const gdb_exception &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ }
ourstatus->set_loaded ();
- thread_id = current_event.dwThreadId;
+ thread_id = current_event->dwThreadId;
break;
case UNLOAD_DLL_DEBUG_EVENT:
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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);
+ try
+ {
+ windows_process.handle_unload_dll ();
+ }
+ catch (const gdb_exception &ex)
+ {
+ exception_print (gdb_stderr, ex);
+ }
ourstatus->set_loaded ();
- thread_id = current_event.dwThreadId;
+ thread_id = current_event->dwThreadId;
break;
case EXCEPTION_DEBUG_EVENT:
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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;
case OUTPUT_DEBUG_STRING_EVENT: /* Message from the kernel. */
DEBUG_EVENTS ("kernel event for pid=%u tid=0x%x code=%s",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
+ (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;
gdb_printf ("gdb: kernel event for pid=%u tid=0x%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId);
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId);
gdb_printf (" unknown event code %u\n",
- (unsigned) current_event.dwDebugEventCode);
+ (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)",
- thread_id, desired_stop_thread_id);
+ thread_id, windows_process.desired_stop_thread_id);
- if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && ((current_event.u.Exception.ExceptionRecord.ExceptionCode
+ if (current_event->dwDebugEventCode == EXCEPTION_DEBUG_EVENT
+ && ((current_event->u.Exception.ExceptionRecord.ExceptionCode
== EXCEPTION_BREAKPOINT)
- || (current_event.u.Exception.ExceptionRecord.ExceptionCode
+ || (current_event->u.Exception.ExceptionRecord.ExceptionCode
== STATUS_WX86_BREAKPOINT))
&& windows_initialization_done)
{
- ptid_t ptid = ptid_t (current_event.dwProcessId, thread_id, 0);
- windows_thread_info *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));
+ CHECK (windows_continue (continue_status,
+ windows_process.desired_stop_thread_id, 0));
}
out:
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 (ourstatus->kind () != TARGET_WAITKIND_EXITED
&& ourstatus->kind () != TARGET_WAITKIND_SIGNALLED)
{
- windows_thread_info *th = thread_rec (result, INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (result, INVALIDATE_CONTEXT);
if (th != nullptr)
{
th->stopped_at_software_breakpoint = false;
- if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && ((current_event.u.Exception.ExceptionRecord.ExceptionCode
+ if (windows_process.current_event.dwDebugEventCode
+ == EXCEPTION_DEBUG_EVENT
+ && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
== EXCEPTION_BREAKPOINT)
- || (current_event.u.Exception.ExceptionRecord.ExceptionCode
+ || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
== STATUS_WX86_BREAKPOINT))
&& windows_initialization_done)
{
int i;
struct inferior *inf;
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
open_process_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));
+ 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);
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);
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;
{
BOOL wow64;
if (IsWow64Process (h, &wow64))
- wow64_process = wow64;
+ windows_process.wow64_process = wow64;
CloseHandle (h);
}
#endif
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);
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."),
#ifdef __x86_64__
BOOL wow64;
if (IsWow64Process (pi.hProcess, &wow64))
- wow64_process = wow64;
+ windows_process.wow64_process = wow64;
#endif
CloseHandle (pi.hThread);
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 ();
}
windows_nat_target::interrupt ()
{
DEBUG_EVENTS ("GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)");
- CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
+ CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT,
+ windows_process.current_event.dwProcessId));
registers_changed (); /* refresh register state */
}
{
DEBUG_MEM ("write target memory, %s bytes at %s",
pulongest (len), core_addr_to_string (memaddr));
- success = WriteProcessMemory (current_process_handle,
+ 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 ("read target memory, %s bytes at %s",
pulongest (len), core_addr_to_string (memaddr));
- success = ReadProcessMemory (current_process_handle,
+ 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;
}
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;
const char *
windows_nat_target::thread_name (struct thread_info *thr)
{
- return thread_rec (thr->ptid, DONT_INVALIDATE_CONTEXT)->name.get ();
+ return windows_process.thread_rec (thr->ptid,
+ DONT_INVALIDATE_CONTEXT)->name.get ();
}
{
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 ();
using namespace windows_nat;
+static windows_process_info windows_process;
+
#ifndef USE_WIN32API
#include <sys/cygwin.h>
#endif
/* 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)
{
thread_info *thread = find_thread_ptid (ptid);
if (thread == NULL)
windows_thread_info *th;
ptid_t ptid = ptid_t (pid, tid, 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;
if (write)
{
- success = WriteProcessMemory (current_process_handle, (LPVOID) addr,
+ success = WriteProcessMemory (windows_process.handle, (LPVOID) addr,
(LPCVOID) our, len, &done);
if (!success)
lasterror = GetLastError ();
- FlushInstructionCache (current_process_handle, (LPCVOID) addr, len);
+ FlushInstructionCache (windows_process.handle, (LPCVOID) addr, len);
}
else
{
- success = ReadProcessMemory (current_process_handle, (LPCVOID) addr,
+ success = ReadProcessMemory (windows_process.handle, (LPCVOID) addr,
(LPVOID) our, len, &done);
if (!success)
lasterror = GetLastError ();
{
struct process_info *proc;
- last_sig = GDB_SIGNAL_0;
-
- current_process_handle = proch;
- current_process_id = pid;
- main_thread_id = 0;
+ windows_process.last_sig = GDB_SIGNAL_0;
+ windows_process.handle = proch;
+ windows_process.id = pid;
+ windows_process.main_thread_id = 0;
soft_interrupt_requested = 0;
faked_breakpoint = 0;
open_process_used = true;
- memset (¤t_event, 0, sizeof (current_event));
+ memset (&windows_process.current_event, 0,
+ sizeof (windows_process.current_event));
#ifdef __x86_64__
BOOL wow64;
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 ();
child_initialization_done = 1;
}
static BOOL
child_continue (DWORD continue_status, int thread_id)
{
- desired_stop_thread_id = thread_id;
- if (matching_pending_stop (debug_threads))
+ windows_process.desired_stop_thread_id = thread_id;
+ if (windows_process.matching_pending_stop (debug_threads))
return TRUE;
/* The inferior will only continue after the ContinueDebugEvent
child_fetch_inferior_registers (struct regcache *regcache, int r)
{
int regno;
- windows_thread_info *th = thread_rec (current_thread_ptid (),
- INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (current_thread_ptid (),
+ INVALIDATE_CONTEXT);
if (r == -1 || r > NUM_REGS)
child_fetch_inferior_registers (regcache, NUM_REGS);
else
child_store_inferior_registers (struct regcache *regcache, int r)
{
int regno;
- windows_thread_info *th = thread_rec (current_thread_ptid (),
- INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (current_thread_ptid (),
+ INVALIDATE_CONTEXT);
if (r == -1 || r == 0 || r > NUM_REGS)
child_store_inferior_registers (regcache, NUM_REGS);
else
/* Wait till we are at 1st instruction in program, return new pid
(assuming success). */
- cs.last_ptid = wait (ptid_t (current_process_id), &cs.last_status, 0);
+ cs.last_ptid = wait (ptid_t (windows_process.id), &cs.last_status, 0);
/* Necessary for handle_v_kill. */
- signal_pid = current_process_id;
+ signal_pid = windows_process.id;
- return current_process_id;
+ return windows_process.id;
}
/* Attach to a running process.
/* 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)
{
#define READ_BUFFER_LEN 1024
CORE_ADDR addr;
{
if (open_process_used)
{
- CloseHandle (current_process_handle);
+ CloseHandle (windows_process.handle);
open_process_used = false;
}
for_each_thread (delete_thread_info);
- siginfo_er.ExceptionCode = 0;
+ windows_process.siginfo_er.ExceptionCode = 0;
clear_inferiors ();
}
int
win32_process_target::kill (process_info *process)
{
- TerminateProcess (current_process_handle, 0);
+ TerminateProcess (windows_process.handle, 0);
for (;;)
{
if (!child_continue (DBG_CONTINUE, -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;
- else if (current_event.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT)
- handle_output_debug_string (nullptr);
+ else if (windows_process.current_event.dwDebugEventCode
+ == OUTPUT_DEBUG_STRING_EVENT)
+ windows_process.handle_output_debug_string (nullptr);
}
win32_clear_inferiors ();
resume.sig = 0;
this->resume (&resume, 1);
- if (!DebugActiveProcessStop (current_process_id))
+ if (!DebugActiveProcessStop (windows_process.id))
return -1;
DebugSetProcessKillOnExit (FALSE);
else
/* Yes, we're ignoring resume_info[0].thread. It'd be tricky to make
the Windows resume code do the right thing for thread switching. */
- tid = current_event.dwThreadId;
+ tid = windows_process.current_event.dwThreadId;
if (resume_info[0].thread != minus_one_ptid)
{
if (sig != GDB_SIGNAL_0)
{
- if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
+ if (windows_process.current_event.dwDebugEventCode
+ != EXCEPTION_DEBUG_EVENT)
{
OUTMSG (("Cannot continue with signal %s here.\n",
gdb_signal_to_string (sig)));
}
- else if (sig == last_sig)
+ else if (sig == windows_process.last_sig)
continue_status = DBG_EXCEPTION_NOT_HANDLED;
else
OUTMSG (("Can only continue with received signal %s.\n",
- gdb_signal_to_string (last_sig)));
+ gdb_signal_to_string (windows_process.last_sig)));
}
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
/* Get context for the currently selected thread. */
- ptid = debug_event_ptid (¤t_event);
- th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
+ ptid = debug_event_ptid (&windows_process.current_event);
+ th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
if (th)
{
win32_prepare_to_resume (th);
/* See nat/windows-nat.h. */
void
-windows_nat::handle_load_dll (const char *name, LPVOID base)
+windows_nat::windows_process_info::handle_load_dll (const char *name,
+ LPVOID base)
{
CORE_ADDR load_addr = (CORE_ADDR) (uintptr_t) base;
/* See nat/windows-nat.h. */
void
-windows_nat::handle_unload_dll ()
+windows_nat::windows_process_info::handle_unload_dll ()
{
CORE_ADDR load_addr =
(CORE_ADDR) (uintptr_t) current_event.u.UnloadDll.lpBaseOfDll;
faked_breakpoint = 1;
- memset (¤t_event, 0, sizeof (current_event));
- current_event.dwThreadId = main_thread_id;
- current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
- current_event.u.Exception.ExceptionRecord.ExceptionCode
+ memset (&windows_process.current_event, 0,
+ sizeof (windows_process.current_event));
+ windows_process.current_event.dwThreadId = windows_process.main_thread_id;
+ windows_process.current_event.dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
+ windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
= EXCEPTION_BREAKPOINT;
for_each_thread (suspend_one_thread);
/* See nat/windows-nat.h. */
bool
-windows_nat::handle_ms_vc_exception (const EXCEPTION_RECORD *rec)
+windows_nat::windows_process_info::handle_ms_vc_exception
+ (const EXCEPTION_RECORD *rec)
{
return false;
}
/* See nat/windows-nat.h. */
bool
-windows_nat::handle_access_violation (const EXCEPTION_RECORD *rec)
+windows_nat::windows_process_info::handle_access_violation
+ (const EXCEPTION_RECORD *rec)
{
return false;
}
struct regcache *regcache = get_thread_regcache (current_thread, 1);
child_fetch_inferior_registers (regcache, -1);
- windows_thread_info *th = thread_rec (current_thread_ptid (),
- DONT_INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (current_thread_ptid (),
+ DONT_INVALIDATE_CONTEXT);
th->stopped_at_software_breakpoint = false;
- if (current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
- && ((current_event.u.Exception.ExceptionRecord.ExceptionCode
+ if (windows_process.current_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT
+ && ((windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
== EXCEPTION_BREAKPOINT)
- || (current_event.u.Exception.ExceptionRecord.ExceptionCode
+ || (windows_process.current_event.u.Exception.ExceptionRecord.ExceptionCode
== STATUS_WX86_BREAKPOINT))
&& child_initialization_done)
{
{
ptid_t ptid;
- last_sig = GDB_SIGNAL_0;
+ windows_process.last_sig = GDB_SIGNAL_0;
ourstatus->set_spurious ();
*continue_status = DBG_CONTINUE;
/* Check if GDB sent us an interrupt request. */
check_remote_input_interrupt_request ();
+ DEBUG_EVENT *current_event = &windows_process.current_event;
+
if (soft_interrupt_requested)
{
soft_interrupt_requested = 0;
attaching = 0;
{
- gdb::optional<pending_stop> stop = fetch_pending_stop (debug_threads);
+ gdb::optional<pending_stop> stop
+ = windows_process.fetch_pending_stop (debug_threads);
if (stop.has_value ())
{
*ourstatus = stop->status;
- current_event = stop->event;
- ptid = debug_event_ptid (¤t_event);
+ windows_process.current_event = stop->event;
+ ptid = debug_event_ptid (&windows_process.current_event);
switch_to_thread (find_thread_ptid (ptid));
return 1;
}
/* Keep the wait time low enough for comfortable remote
interruption, but high enough so gdbserver doesn't become a
bottleneck. */
- if (!wait_for_debug_event (¤t_event, 250))
+ if (!wait_for_debug_event (&windows_process.current_event, 250))
{
DWORD e = GetLastError();
gotevent:
- switch (current_event.dwDebugEventCode)
+ switch (current_event->dwDebugEventCode)
{
case CREATE_THREAD_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event CREATE_THREAD_DEBUG_EVENT "
"for pid=%u tid=%x)\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
/* Record the existence of this thread. */
- child_add_thread (current_event.dwProcessId,
- current_event.dwThreadId,
- current_event.u.CreateThread.hThread,
- current_event.u.CreateThread.lpThreadLocalBase);
+ child_add_thread (current_event->dwProcessId,
+ current_event->dwThreadId,
+ current_event->u.CreateThread.hThread,
+ current_event->u.CreateThread.lpThreadLocalBase);
break;
case EXIT_THREAD_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXIT_THREAD_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- child_delete_thread (current_event.dwProcessId,
- current_event.dwThreadId);
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
+ child_delete_thread (current_event->dwProcessId,
+ current_event->dwThreadId);
switch_to_thread (get_first_thread ());
return 1;
case CREATE_PROCESS_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event CREATE_PROCESS_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- CloseHandle (current_event.u.CreateProcessInfo.hFile);
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
+ CloseHandle (current_event->u.CreateProcessInfo.hFile);
if (open_process_used)
{
- CloseHandle (current_process_handle);
+ CloseHandle (windows_process.handle);
open_process_used = false;
}
- current_process_handle = current_event.u.CreateProcessInfo.hProcess;
- main_thread_id = current_event.dwThreadId;
+ windows_process.handle = current_event->u.CreateProcessInfo.hProcess;
+ windows_process.main_thread_id = current_event->dwThreadId;
/* Add the main thread. */
- child_add_thread (current_event.dwProcessId,
- main_thread_id,
- current_event.u.CreateProcessInfo.hThread,
- current_event.u.CreateProcessInfo.lpThreadLocalBase);
+ child_add_thread (current_event->dwProcessId,
+ windows_process.main_thread_id,
+ current_event->u.CreateProcessInfo.hThread,
+ current_event->u.CreateProcessInfo.lpThreadLocalBase);
break;
case EXIT_PROCESS_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXIT_PROCESS_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
{
- 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 information. */
else
ourstatus->set_signalled (gdb_signal_from_host (exit_signal));
}
- child_continue (DBG_CONTINUE, desired_stop_thread_id);
+ child_continue (DBG_CONTINUE, windows_process.desired_stop_thread_id);
break;
case LOAD_DLL_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event LOAD_DLL_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- CloseHandle (current_event.u.LoadDll.hFile);
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
+ CloseHandle (current_event->u.LoadDll.hFile);
if (! child_initialization_done)
break;
- dll_loaded_event ();
+ windows_process.dll_loaded_event ();
ourstatus->set_loaded ();
break;
case UNLOAD_DLL_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event UNLOAD_DLL_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
if (! child_initialization_done)
break;
- handle_unload_dll ();
+ windows_process.handle_unload_dll ();
ourstatus->set_loaded ();
break;
case EXCEPTION_DEBUG_EVENT:
OUTMSG2 (("gdbserver: kernel event EXCEPTION_DEBUG_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- if (handle_exception (ourstatus, debug_threads)
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
+ if (windows_process.handle_exception (ourstatus, debug_threads)
== HANDLE_EXCEPTION_UNHANDLED)
*continue_status = DBG_EXCEPTION_NOT_HANDLED;
break;
/* A message from the kernel (or Cygwin). */
OUTMSG2 (("gdbserver: kernel event OUTPUT_DEBUG_STRING_EVENT "
"for pid=%u tid=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId));
- handle_output_debug_string (nullptr);
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId));
+ windows_process.handle_output_debug_string (nullptr);
break;
default:
OUTMSG2 (("gdbserver: kernel event unknown "
"for pid=%u tid=%x code=%x\n",
- (unsigned) current_event.dwProcessId,
- (unsigned) current_event.dwThreadId,
- (unsigned) current_event.dwDebugEventCode));
+ (unsigned) current_event->dwProcessId,
+ (unsigned) current_event->dwThreadId,
+ (unsigned) current_event->dwDebugEventCode));
break;
}
- ptid = debug_event_ptid (¤t_event);
+ ptid = debug_event_ptid (&windows_process.current_event);
- if (desired_stop_thread_id != -1 && desired_stop_thread_id != ptid.lwp ())
+ if (windows_process.desired_stop_thread_id != -1
+ && windows_process.desired_stop_thread_id != ptid.lwp ())
{
/* Pending stop. See the comment by the definition of
"pending_stops" for details on why this is needed. */
OUTMSG2 (("get_windows_debug_event - "
"unexpected stop in 0x%lx (expecting 0x%x)\n",
- ptid.lwp (), desired_stop_thread_id));
+ ptid.lwp (), windows_process.desired_stop_thread_id));
maybe_adjust_pc ();
- pending_stops.push_back ({(DWORD) ptid.lwp (), *ourstatus, current_event});
+ windows_process.pending_stops.push_back
+ ({(DWORD) ptid.lwp (), *ourstatus, *current_event});
ourstatus->set_spurious ();
}
else
fails). Report it now. */
*ourstatus = cached_status;
cached_status.set_ignore ();
- return debug_event_ptid (¤t_event);
+ return debug_event_ptid (&windows_process.current_event);
}
while (1)
OUTMSG2 (("Child exited with retcode = %x\n",
ourstatus->exit_status ()));
win32_clear_inferiors ();
- return ptid_t (current_event.dwProcessId);
+ return ptid_t (windows_process.current_event.dwProcessId);
case TARGET_WAITKIND_STOPPED:
case TARGET_WAITKIND_SIGNALLED:
case TARGET_WAITKIND_LOADED:
OUTMSG2 (("Child Stopped with signal = %d \n",
ourstatus->sig ()));
maybe_adjust_pc ();
- return debug_event_ptid (¤t_event);
+ return debug_event_ptid (&windows_process.current_event);
}
default:
OUTMSG (("Ignoring unknown internal event, %d\n",
/* fall-through */
case TARGET_WAITKIND_SPURIOUS:
/* do nothing, just continue */
- child_continue (continue_status, desired_stop_thread_id);
+ child_continue (continue_status,
+ windows_process.desired_stop_thread_id);
break;
}
}
void
win32_process_target::request_interrupt ()
{
- if (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, current_process_id))
+ if (GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, windows_process.id))
return;
/* GenerateConsoleCtrlEvent can fail if process id being debugged is
Fallback to XP/Vista 'DebugBreakProcess', which generates a
breakpoint exception in the interior process. */
- if (DebugBreakProcess (current_process_handle))
+ if (DebugBreakProcess (windows_process.handle))
return;
/* Last resort, suspend all threads manually. */
unsigned const char *writebuf,
CORE_ADDR offset, int len)
{
- if (siginfo_er.ExceptionCode == 0)
+ if (windows_process.siginfo_er.ExceptionCode == 0)
return -1;
if (readbuf == nullptr)
return -1;
- 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;
win32_process_target::get_tib_address (ptid_t ptid, CORE_ADDR *addr)
{
windows_thread_info *th;
- th = thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
+ th = windows_process.thread_rec (ptid, DONT_INVALIDATE_CONTEXT);
if (th == NULL)
return 0;
if (addr != NULL)
bool
win32_process_target::stopped_by_sw_breakpoint ()
{
- windows_thread_info *th = thread_rec (current_thread_ptid (),
- DONT_INVALIDATE_CONTEXT);
+ windows_thread_info *th
+ = windows_process.thread_rec (current_thread_ptid (),
+ DONT_INVALIDATE_CONTEXT);
return th == nullptr ? false : th->stopped_at_software_breakpoint;
}