diff options
Diffstat (limited to 'gdb/nat/windows-nat.h')
-rw-r--r-- | gdb/nat/windows-nat.h | 217 |
1 files changed, 117 insertions, 100 deletions
diff --git a/gdb/nat/windows-nat.h b/gdb/nat/windows-nat.h index bfb359e..7f76ba0 100644 --- a/gdb/nat/windows-nat.h +++ b/gdb/nat/windows-nat.h @@ -109,145 +109,162 @@ enum thread_disposition_type 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 |