19#include "gdbsupport/common-defs.h"
21#include "gdbsupport/common-debug.h"
22#include "target/target.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
142 ((
char *) xmalloc (needed));
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"),
210 err, strwinerror (err));
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"),
223 err, strwinerror (err));
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)
337 gdb::unique_xmalloc_ptr<char> thread_name
338 = target_read_string (thread_name_target, 1025, &thread_name_len);
339 if (thread_name_len > 0)
341 thread_name.get ()[thread_name_len - 1] =
'\0';
342 named_thread->
name = std::move (thread_name);
356#define MS_VC_EXCEPTION 0x406d1388
360 bool debug_exceptions)
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:
383 ourstatus->set_stopped (GDB_SIGNAL_SEGV);
387 case STATUS_STACK_OVERFLOW:
389 ourstatus->set_stopped (GDB_SIGNAL_SEGV);
391 case STATUS_FLOAT_DENORMAL_OPERAND:
393 ourstatus->set_stopped (GDB_SIGNAL_FPE);
395 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
397 ourstatus->set_stopped (GDB_SIGNAL_FPE);
399 case STATUS_FLOAT_INEXACT_RESULT:
401 ourstatus->set_stopped (GDB_SIGNAL_FPE);
403 case STATUS_FLOAT_INVALID_OPERATION:
405 ourstatus->set_stopped (GDB_SIGNAL_FPE);
407 case STATUS_FLOAT_OVERFLOW:
409 ourstatus->set_stopped (GDB_SIGNAL_FPE);
411 case STATUS_FLOAT_STACK_CHECK:
413 ourstatus->set_stopped (GDB_SIGNAL_FPE);
415 case STATUS_FLOAT_UNDERFLOW:
417 ourstatus->set_stopped (GDB_SIGNAL_FPE);
419 case STATUS_FLOAT_DIVIDE_BY_ZERO:
421 ourstatus->set_stopped (GDB_SIGNAL_FPE);
423 case STATUS_INTEGER_DIVIDE_BY_ZERO:
425 ourstatus->set_stopped (GDB_SIGNAL_FPE);
427 case STATUS_INTEGER_OVERFLOW:
429 ourstatus->set_stopped (GDB_SIGNAL_FPE);
431 case EXCEPTION_BREAKPOINT:
433 if (ignore_first_breakpoint)
440 ourstatus->set_spurious ();
441 ignore_first_breakpoint =
false;
444 else if (wow64_process)
454 rec->ExceptionCode = DBG_CONTROL_C;
455 ourstatus->set_stopped (GDB_SIGNAL_INT);
462 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
466 ourstatus->set_stopped (GDB_SIGNAL_INT);
468 case DBG_CONTROL_BREAK:
470 ourstatus->set_stopped (GDB_SIGNAL_INT);
472 case EXCEPTION_SINGLE_STEP:
475 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
477 case EXCEPTION_ILLEGAL_INSTRUCTION:
479 ourstatus->set_stopped (GDB_SIGNAL_ILL);
481 case EXCEPTION_PRIV_INSTRUCTION:
483 ourstatus->set_stopped (GDB_SIGNAL_ILL);
485 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
487 ourstatus->set_stopped (GDB_SIGNAL_ILL);
493 ourstatus->set_stopped (GDB_SIGNAL_TRAP);
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));
507 ourstatus->set_stopped (GDB_SIGNAL_UNKNOWN);
511 if (ourstatus->kind () == TARGET_WAITKIND_STOPPED)
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>
782 CHAR *command_line, DWORD flags,
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;
831 BOOL result = do_create_process (image, command_line,
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);
886create_process (
const wchar_t *image,
wchar_t *command_line, DWORD flags,
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"));
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)
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
#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