19#include "gdbsupport/common-defs.h"
21#include "gdbsupport/common-debug.h"
24#undef GetModuleFileNameEx
27#define GetModuleFileNameEx GetModuleFileNameExA
29#include <sys/cygwin.h>
31#define GetModuleFileNameEx GetModuleFileNameExW
67#define GetThreadDescription dyn_GetThreadDescription
77#define DEBUG_EVENTS(fmt, ...) \
78 debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
87 if (SuspendThread (
h) == (DWORD) -1)
89 DWORD
err = GetLastError ();
97 if (
err != ERROR_INVALID_HANDLE &&
err != ERROR_ACCESS_DENIED)
98 warning (_(
"SuspendThread (tid=0x%x) failed. (winerr %u: %s)"),
99 (
unsigned)
tid, (
unsigned)
err, strwinerror (
err));
113 if (ResumeThread (
h) == (DWORD) -1)
115 DWORD
err = GetLastError ();
116 warning (_(
"warning: ResumeThread (tid=0x%x) failed. (winerr %u: %s)"),
117 (
unsigned)
tid, (
unsigned)
err, strwinerror (
err));
130 if (SUCCEEDED (result))
132 int needed = WideCharToMultiByte (CP_ACP, 0,
value, -1,
nullptr, 0,
140 BOOL used_default = FALSE;
141 gdb::unique_xmalloc_ptr<char> new_name
143 if (WideCharToMultiByte (CP_ACP, 0,
value, -1,
144 new_name.get (), needed,
145 nullptr, &used_default) == needed
147 && strlen (new_name.get ()) > 0)
148 name = std::move (new_name);
169 size_t exe_name_max_len)
180 &dh_buf,
sizeof (HMODULE), &cbNeeded,
189 &dh_buf,
sizeof (HMODULE), &cbNeeded)
202 wchar_t *pathbuf = (
wchar_t *) alloca (exe_name_max_len *
sizeof (
wchar_t));
205 dh_buf, pathbuf, exe_name_max_len);
208 unsigned err = (unsigned) GetLastError ();
209 error (_(
"Error getting executable filename (error %u): %s"),
212 if (cygwin_conv_path (CCP_WIN_W_TO_POSIX, pathbuf, exe_name_ret,
213 exe_name_max_len) < 0)
214 error (_(
"Error converting executable filename to POSIX: %d."), errno);
218 dh_buf, exe_name_ret, exe_name_max_len);
221 unsigned err = (unsigned) GetLastError ();
222 error (_(
"Error getting executable filename (error %u): %s"),
233 static char path[MAX_PATH];
237 char procexe[
sizeof (
"/proc/4294967295/exe")];
239 xsnprintf (procexe,
sizeof (procexe),
"/proc/%u/exe",
pid);
240 nchars = readlink (procexe, path,
sizeof(path));
241 if (nchars > 0 && nchars <
sizeof (path))
266 static char buf[MAX_PATH];
268 static char buf[(2 * MAX_PATH) + 1];
270 DWORD
size = unicode ?
sizeof (WCHAR) :
sizeof (char);
284 if (!ReadProcessMemory (h, address, &address_ptr,
285 sizeof (address_ptr), &done)
286 || done !=
sizeof (address_ptr)
291 while (ReadProcessMemory (h, address_ptr + len++ *
size, &b,
size, &done)
292 && (b[0] != 0 || b[
size - 1] != 0) && done ==
size)
296 ReadProcessMemory (h, address_ptr, buf, len, &done);
299 WCHAR *unicode_address = (WCHAR *) alloca (len *
sizeof (WCHAR));
300 ReadProcessMemory (h, address_ptr, unicode_address, len *
sizeof (WCHAR),
303 wcstombs (buf, unicode_address, MAX_PATH);
305 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf,
sizeof buf,
318 if (rec->NumberParameters >= 3
319 && (rec->ExceptionInformation[0] & 0xffffffff) == 0x1000)
321 DWORD named_thread_id;
323 CORE_ADDR thread_name_target;
325 thread_name_target = rec->ExceptionInformation[1];
326 named_thread_id = (DWORD) (0xffffffff & rec->ExceptionInformation[2]);
328 if (named_thread_id == (DWORD) -1)
334 if (named_thread != NULL)
339 if (thread_name_len > 0)
356#define MS_VC_EXCEPTION 0x406d1388
362#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
363 debug_printf ("gdb: Target exception %s at %s\n", x, \
364 host_address_to_string (\
365 current_event.u.Exception.ExceptionRecord.ExceptionAddress))
367 EXCEPTION_RECORD *rec = &
current_event.u.Exception.ExceptionRecord;
368 DWORD
code = rec->ExceptionCode;
381 case EXCEPTION_ACCESS_VIOLATION:
387 case STATUS_STACK_OVERFLOW:
391 case STATUS_FLOAT_DENORMAL_OPERAND:
395 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
399 case STATUS_FLOAT_INEXACT_RESULT:
403 case STATUS_FLOAT_INVALID_OPERATION:
407 case STATUS_FLOAT_OVERFLOW:
411 case STATUS_FLOAT_STACK_CHECK:
415 case STATUS_FLOAT_UNDERFLOW:
419 case STATUS_FLOAT_DIVIDE_BY_ZERO:
423 case STATUS_INTEGER_DIVIDE_BY_ZERO:
427 case STATUS_INTEGER_OVERFLOW:
431 case EXCEPTION_BREAKPOINT:
433 if (ignore_first_breakpoint)
441 ignore_first_breakpoint =
false;
444 else if (wow64_process)
454 rec->ExceptionCode = DBG_CONTROL_C;
468 case DBG_CONTROL_BREAK:
472 case EXCEPTION_SINGLE_STEP:
477 case EXCEPTION_ILLEGAL_INSTRUCTION:
481 case EXCEPTION_PRIV_INSTRUCTION:
485 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
503 debug_printf (
"gdb: unknown target exception 0x%08x at %s\n",
504 (
unsigned)
current_event.u.Exception.ExceptionRecord.ExceptionCode,
505 host_address_to_string (
506 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
516#undef DEBUG_EXCEPTION_SIMPLE
524 HMODULE dummy_hmodule;
533 sizeof (HMODULE), &cb_needed,
534 LIST_MODULES_32BIT) == 0)
541 sizeof (HMODULE), &cb_needed) == 0)
548 hmodules = (HMODULE *) alloca (cb_needed);
553 cb_needed, &cb_needed,
554 LIST_MODULES_32BIT) == 0)
561 cb_needed, &cb_needed) == 0)
565 char system_dir[MAX_PATH];
566 char syswow_dir[MAX_PATH];
567 size_t system_dir_len = 0;
568 bool convert_syswow_dir =
false;
575 UINT len = GetSystemWow64DirectoryA (syswow_dir,
sizeof (syswow_dir));
579 gdb_assert (len <
sizeof (syswow_dir));
581 len = GetSystemDirectoryA (system_dir,
sizeof (system_dir));
583 gdb_assert (len != 0);
585 gdb_assert (len <
sizeof (system_dir));
587 strcat (system_dir,
"\\");
588 strcat (syswow_dir,
"\\");
589 system_dir_len = strlen (system_dir);
591 convert_syswow_dir =
true;
595 for (i = 1; i < (int) (cb_needed /
sizeof (HMODULE)); i++)
599 wchar_t dll_name[MAX_PATH];
600 char dll_name_mb[MAX_PATH];
602 char dll_name[MAX_PATH];
606 &mi,
sizeof (mi)) == 0)
610 dll_name,
sizeof (dll_name)) == 0)
613 wcstombs (dll_name_mb, dll_name, MAX_PATH);
621 std::string syswow_dll_path;
622 if (convert_syswow_dir
623 && strncasecmp (
name, system_dir, system_dir_len) == 0
624 && strchr (
name + system_dir_len,
'\\') ==
nullptr)
626 syswow_dll_path = syswow_dir;
627 syswow_dll_path +=
name + system_dir_len;
628 name = syswow_dll_path.c_str();
633 if (!(load_addr !=
nullptr && mi.lpBaseOfDll != load_addr))
636 if (load_addr !=
nullptr)
647 gdb_assert (
current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);
650 const char *dll_name;
661 if (dll_name !=
nullptr)
663 else if (event->lpBaseOfDll !=
nullptr)
690 DEBUG_EVENTS (
"pending stop anticipated, desired=0x%x, item=0x%x",
701gdb::optional<pending_stop>
704 gdb::optional<pending_stop> result;
715 DEBUG_EVENTS (
"pending stop found in 0x%x (desired=0x%x)",
731 DEBUG_EVENTS (
"ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
734 continue_status == DBG_CONTINUE ?
735 "DBG_CONTINUE" :
"DBG_EXCEPTION_NOT_HANDLED");
747 BOOL result = WaitForDebugEvent (event, timeout);
754#define relocate_aslr_flags ((0x2 << 8) | (0x2 << 16))
757#define mitigation_policy 0x00020007
760#ifdef PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
762static_assert ((PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
763 | PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_OFF)
765 "check that ASLR flag values are correct");
768 "check that mitigation policy value is correct");
779template<
typename FUNC,
typename CHAR,
typename INFO>
783 void *environment,
const CHAR *cur_dir,
784 bool no_randomization,
786 PROCESS_INFORMATION *process_info)
790 static bool tried_and_failed;
792 if (!tried_and_failed)
797 struct gdb_extended_info
803# ifndef EXTENDED_STARTUPINFO_PRESENT
804# define EXTENDED_STARTUPINFO_PRESENT 0x00080000
807 gdb_extended_info info_ex {};
809 if (startup_info !=
nullptr)
810 info_ex.StartupInfo = *startup_info;
811 info_ex.StartupInfo.cb =
sizeof (info_ex);
816 info_ex.lpAttributeList
821 gdb::optional<BOOL> return_value;
828 tried_and_failed =
true;
838 &info_ex.StartupInfo,
841 return_value = result;
842 else if (GetLastError () == ERROR_INVALID_PARAMETER)
843 tried_and_failed =
true;
845 return_value = FALSE;
850 if (return_value.has_value ())
851 return *return_value;
855 return do_create_process (image,
871 void *environment,
const char *cur_dir,
872 bool no_randomization,
873 STARTUPINFOA *startup_info,
874 PROCESS_INFORMATION *process_info)
877 environment, cur_dir, no_randomization,
878 startup_info, process_info);
887 void *environment,
const wchar_t *cur_dir,
888 bool no_randomization,
889 STARTUPINFOW *startup_info,
890 PROCESS_INFORMATION *process_info)
893 environment, cur_dir, no_randomization,
894 startup_info, process_info);
901template<
typename...
T>
908template<
typename...
T>
949#define GPA(m, func) \
950 func = (func ## _ftype *) GetProcAddress (m, #func)
952 hm = LoadLibrary (
TEXT (
"kernel32.dll"));
991 hm = LoadLibrary (
TEXT (
"psapi.dll"));
1016 hm = LoadLibrary (
TEXT (
"advapi32.dll"));
1033 hm = LoadLibrary (
TEXT (
"KernelBase.dll"));
const char * thread_name(thread_info *thread)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
mach_port_t kern_return_t mach_port_t mach_msg_type_name_t msgportsPoly mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int flags
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
GenerateConsoleCtrlEvent_ftype * GenerateConsoleCtrlEvent
DeleteProcThreadAttributeList_ftype * DeleteProcThreadAttributeList
GetCurrentConsoleFont_ftype * GetCurrentConsoleFont
GetModuleFileNameExA_ftype * GetModuleFileNameExA
BOOL WINAPI GetModuleInformation_ftype(HANDLE, HMODULE, LPMODULEINFO, DWORD)
BOOL WINAPI OpenProcessToken_ftype(HANDLE, DWORD, PHANDLE)
DWORD WINAPI GetModuleFileNameExW_ftype(HANDLE, HMODULE, LPWSTR, DWORD)
BOOL WINAPI GenerateConsoleCtrlEvent_ftype(DWORD, DWORD)
BOOL WINAPI UpdateProcThreadAttribute_ftype(gdb_lpproc_thread_attribute_list lpAttributeList, DWORD dwFlags, DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize, PVOID lpPreviousValue, PSIZE_T lpReturnSize)
BOOL WINAPI LookupPrivilegeValueA_ftype(LPCSTR, LPCSTR, PLUID)
static GetThreadDescription_ftype * GetThreadDescription
BOOL create_process(const char *image, char *command_line, DWORD flags, void *environment, const char *cur_dir, bool no_randomization, STARTUPINFOA *startup_info, PROCESS_INFORMATION *process_info)
static COORD WINAPI bad_GetConsoleFontSize(HANDLE w, DWORD nFont)
DebugActiveProcessStop_ftype * DebugActiveProcessStop
BOOL WINAPI DebugBreakProcess_ftype(HANDLE)
bool initialize_loadable()
BOOL WINAPI GetCurrentConsoleFont_ftype(HANDLE, BOOL, CONSOLE_FONT_INFO *)
HRESULT WINAPI GetThreadDescription_ftype(HANDLE, PWSTR *)
InitializeProcThreadAttributeList_ftype * InitializeProcThreadAttributeList
DebugBreakProcess_ftype * DebugBreakProcess
BOOL wait_for_debug_event(DEBUG_EVENT *event, DWORD timeout)
BOOL WINAPI AdjustTokenPrivileges_ftype(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD)
LookupPrivilegeValueA_ftype * LookupPrivilegeValueA
UpdateProcThreadAttribute_ftype * UpdateProcThreadAttribute
OpenProcessToken_ftype * OpenProcessToken
BOOL WINAPI DebugActiveProcessStop_ftype(DWORD)
BOOL WINAPI bad(T... args)
GetConsoleFontSize_ftype * GetConsoleFontSize
DWORD WINAPI GetModuleFileNameExA_ftype(HANDLE, HMODULE, LPSTR, DWORD)
BOOL create_process_wrapper(FUNC *do_create_process, const CHAR *image, CHAR *command_line, DWORD flags, void *environment, const CHAR *cur_dir, bool no_randomization, INFO *startup_info, PROCESS_INFORMATION *process_info)
BOOL WINAPI EnumProcessModules_ftype(HANDLE, HMODULE *, DWORD, LPDWORD)
AdjustTokenPrivileges_ftype * AdjustTokenPrivileges
DebugSetProcessKillOnExit_ftype * DebugSetProcessKillOnExit
GetModuleFileNameExW_ftype * GetModuleFileNameExW
static const char * get_image_name(HANDLE h, void *address, int unicode)
void * gdb_lpproc_thread_attribute_list
BOOL WINAPI InitializeProcThreadAttributeList_ftype(gdb_lpproc_thread_attribute_list lpAttributeList, DWORD dwAttributeCount, DWORD dwFlags, PSIZE_T lpSize)
static BOOL WINAPI bad_GetCurrentConsoleFont(HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
@ HANDLE_EXCEPTION_IGNORED
@ HANDLE_EXCEPTION_HANDLED
@ HANDLE_EXCEPTION_UNHANDLED
void WINAPI DeleteProcThreadAttributeList_ftype(gdb_lpproc_thread_attribute_list lpAttributeList)
BOOL WINAPI DebugSetProcessKillOnExit_ftype(BOOL)
EnumProcessModules_ftype * EnumProcessModules
@ DONT_INVALIDATE_CONTEXT
BOOL continue_last_debug_event(DWORD continue_status, bool debug_events)
static DEBUG_EVENT last_wait_event
GetModuleInformation_ftype * GetModuleInformation
bool disable_randomization_available()
COORD WINAPI GetConsoleFontSize_ftype(HANDLE, DWORD)
#define GetModuleFileNameEx
#define DEBUG_EXCEPTION_SIMPLE(x)
#define DEBUG_EVENTS(fmt,...)
#define relocate_aslr_flags
#define EXTENDED_STARTUPINFO_PRESENT
#define mitigation_policy
#define Wow64GetThreadSelectorEntry
#define Wow64SetThreadContext
#define STATUS_WX86_SINGLE_STEP
#define EnumProcessModulesEx
#define Wow64GetThreadContext
#define STATUS_WX86_BREAKPOINT
#define Wow64SuspendThread
target_waitstatus & set_spurious()
target_waitstatus & set_stopped(gdb_signal sig)
target_waitkind kind() const
bool matching_pending_stop(bool debug_events)
virtual windows_thread_info * thread_rec(ptid_t ptid, thread_disposition_type disposition)=0
gdb::optional< pending_stop > fetch_pending_stop(bool debug_events)
virtual void handle_load_dll(const char *dll_name, LPVOID base)=0
DWORD desired_stop_thread_id
void add_dll(LPVOID load_addr)
EXCEPTION_RECORD siginfo_er
handle_exception_result handle_exception(struct target_waitstatus *ourstatus, bool debug_exceptions)
const char * pid_to_exec_file(int)
DEBUG_EVENT current_event
std::vector< pending_stop > pending_stops
bool handle_ms_vc_exception(const EXCEPTION_RECORD *rec)
virtual bool handle_access_violation(const EXCEPTION_RECORD *rec)=0
int get_exec_module_filename(char *exe_name_ret, size_t exe_name_max_len)
gdb::unique_xmalloc_ptr< char > name
const char * thread_name()
bool stopped_at_software_breakpoint
int target_read_string(CORE_ADDR addr, int len, int width, unsigned int fetchlimit, gdb::unique_xmalloc_ptr< gdb_byte > *buffer, int *bytes_read)
@ TARGET_WAITKIND_STOPPED
static bool debug_exceptions