1 /* Internal interfaces for the Windows code
2 Copyright (C) 1995-2023 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "gdbsupport/common-defs.h"
20 #include "nat/windows-nat.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
37 /* The most recent event from WaitForDebugEvent. Unlike
38 current_event, this is guaranteed never to come from a pending
39 stop. This is important because only data from the most recent
40 event from WaitForDebugEvent can be used when calling
41 ContinueDebugEvent. */
42 static DEBUG_EVENT last_wait_event
;
44 AdjustTokenPrivileges_ftype
*AdjustTokenPrivileges
;
45 DebugActiveProcessStop_ftype
*DebugActiveProcessStop
;
46 DebugBreakProcess_ftype
*DebugBreakProcess
;
47 DebugSetProcessKillOnExit_ftype
*DebugSetProcessKillOnExit
;
48 EnumProcessModules_ftype
*EnumProcessModules
;
50 EnumProcessModulesEx_ftype
*EnumProcessModulesEx
;
52 GetModuleInformation_ftype
*GetModuleInformation
;
53 GetModuleFileNameExA_ftype
*GetModuleFileNameExA
;
54 GetModuleFileNameExW_ftype
*GetModuleFileNameExW
;
55 LookupPrivilegeValueA_ftype
*LookupPrivilegeValueA
;
56 OpenProcessToken_ftype
*OpenProcessToken
;
57 GetCurrentConsoleFont_ftype
*GetCurrentConsoleFont
;
58 GetConsoleFontSize_ftype
*GetConsoleFontSize
;
60 Wow64SuspendThread_ftype
*Wow64SuspendThread
;
61 Wow64GetThreadContext_ftype
*Wow64GetThreadContext
;
62 Wow64SetThreadContext_ftype
*Wow64SetThreadContext
;
63 Wow64GetThreadSelectorEntry_ftype
*Wow64GetThreadSelectorEntry
;
65 GenerateConsoleCtrlEvent_ftype
*GenerateConsoleCtrlEvent
;
67 #define GetThreadDescription dyn_GetThreadDescription
68 typedef HRESULT
WINAPI (GetThreadDescription_ftype
) (HANDLE
, PWSTR
*);
69 static GetThreadDescription_ftype
*GetThreadDescription
;
71 InitializeProcThreadAttributeList_ftype
*InitializeProcThreadAttributeList
;
72 UpdateProcThreadAttribute_ftype
*UpdateProcThreadAttribute
;
73 DeleteProcThreadAttributeList_ftype
*DeleteProcThreadAttributeList
;
75 /* Note that 'debug_events' must be locally defined in the relevant
77 #define DEBUG_EVENTS(fmt, ...) \
78 debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
82 windows_thread_info::suspend ()
87 if (SuspendThread (h
) == (DWORD
) -1)
89 DWORD err
= GetLastError ();
91 /* We get Access Denied (5) when trying to suspend
92 threads that Windows started on behalf of the
93 debuggee, usually when those threads are just
95 We can get Invalid Handle (6) if the main thread
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
));
107 windows_thread_info::resume ()
111 stopped_at_software_breakpoint
= false;
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
));
124 windows_thread_info::thread_name ()
126 if (GetThreadDescription
!= nullptr)
129 HRESULT result
= GetThreadDescription (h
, &value
);
130 if (SUCCEEDED (result
))
132 int needed
= WideCharToMultiByte (CP_ACP
, 0, value
, -1, nullptr, 0,
136 /* USED_DEFAULT is how we detect that the encoding
137 conversion had to fall back to the substitution
138 character. It seems better to just reject bad
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
);
157 /* Try to determine the executable filename.
159 EXE_NAME_RET is a pointer to a buffer whose size is EXE_NAME_MAX_LEN.
161 Upon success, the filename is stored inside EXE_NAME_RET, and
162 this function returns nonzero.
164 Otherwise, this function returns zero and the contents of
165 EXE_NAME_RET is undefined. */
168 windows_process_info::get_exec_module_filename (char *exe_name_ret
,
169 size_t exe_name_max_len
)
179 if (!EnumProcessModulesEx (handle
,
180 &dh_buf
, sizeof (HMODULE
), &cbNeeded
,
188 if (!EnumProcessModules (handle
,
189 &dh_buf
, sizeof (HMODULE
), &cbNeeded
)
194 /* We know the executable is always first in the list of modules,
195 which we just fetched. So no need to fetch more. */
199 /* Cygwin prefers that the path be in /x/y/z format, so extract
200 the filename into a temporary buffer first, and then convert it
201 to POSIX format into the destination buffer. */
202 wchar_t *pathbuf
= (wchar_t *) alloca (exe_name_max_len
* sizeof (wchar_t));
204 len
= GetModuleFileNameEx (handle
,
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
);
217 len
= GetModuleFileNameEx (handle
,
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
));
227 return 1; /* success */
231 windows_process_info::pid_to_exec_file (int pid
)
233 static char path
[MAX_PATH
];
235 /* Try to find exe name as symlink target of /proc/<pid>/exe. */
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
))
243 path
[nchars
] = '\0'; /* Got it */
248 /* If we get here then either Cygwin is hosed, this isn't a Cygwin version
249 of gdb, or we're trying to debug a non-Cygwin windows executable. */
250 if (!get_exec_module_filename (path
, sizeof (path
)))
256 /* Return the name of the DLL referenced by H at ADDRESS. UNICODE
257 determines what sort of string is read from the inferior. Returns
258 the name of the DLL, or NULL on error. If a name is returned, it
259 is stored in a static buffer which is valid until the next call to
263 get_image_name (HANDLE h
, void *address
, int unicode
)
266 static char buf
[MAX_PATH
];
268 static char buf
[(2 * MAX_PATH
) + 1];
270 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
276 /* Attempt to read the name of the dll that was detected.
277 This is documented to work only when actively debugging
278 a program. It will not work for attached processes. */
282 /* See if we could read the address of a string, and that the
283 address isn't null. */
284 if (!ReadProcessMemory (h
, address
, &address_ptr
,
285 sizeof (address_ptr
), &done
)
286 || done
!= sizeof (address_ptr
)
290 /* Find the length of the string. */
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
,
313 /* See nat/windows-nat.h. */
316 windows_process_info::handle_ms_vc_exception (const EXCEPTION_RECORD
*rec
)
318 if (rec
->NumberParameters
>= 3
319 && (rec
->ExceptionInformation
[0] & 0xffffffff) == 0x1000)
321 DWORD named_thread_id
;
322 windows_thread_info
*named_thread
;
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)
329 named_thread_id
= current_event
.dwThreadId
;
331 named_thread
= thread_rec (ptid_t (current_event
.dwProcessId
,
333 DONT_INVALIDATE_CONTEXT
);
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
);
352 /* The exception thrown by a program to tell the debugger the name of
353 a thread. The exception record contains an ID of a thread and a
354 name to give it. This exception has no documented name, but MSDN
355 dubs it "MS_VC_EXCEPTION" in one code example. */
356 #define MS_VC_EXCEPTION 0x406d1388
358 handle_exception_result
359 windows_process_info::handle_exception (struct target_waitstatus
*ourstatus
,
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
= ¤t_event
.u
.Exception
.ExceptionRecord
;
368 DWORD code
= rec
->ExceptionCode
;
369 handle_exception_result result
= HANDLE_EXCEPTION_HANDLED
;
371 memcpy (&siginfo_er
, rec
, sizeof siginfo_er
);
373 /* Record the context of the current thread. */
374 thread_rec (ptid_t (current_event
.dwProcessId
, current_event
.dwThreadId
, 0),
377 last_sig
= GDB_SIGNAL_0
;
381 case EXCEPTION_ACCESS_VIOLATION
:
382 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
383 ourstatus
->set_stopped (GDB_SIGNAL_SEGV
);
384 if (handle_access_violation (rec
))
385 return HANDLE_EXCEPTION_UNHANDLED
;
387 case STATUS_STACK_OVERFLOW
:
388 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
389 ourstatus
->set_stopped (GDB_SIGNAL_SEGV
);
391 case STATUS_FLOAT_DENORMAL_OPERAND
:
392 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
393 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
395 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
396 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
397 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
399 case STATUS_FLOAT_INEXACT_RESULT
:
400 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
401 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
403 case STATUS_FLOAT_INVALID_OPERATION
:
404 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
405 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
407 case STATUS_FLOAT_OVERFLOW
:
408 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
409 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
411 case STATUS_FLOAT_STACK_CHECK
:
412 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
413 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
415 case STATUS_FLOAT_UNDERFLOW
:
416 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
417 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
419 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
420 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
421 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
423 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
424 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
425 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
427 case STATUS_INTEGER_OVERFLOW
:
428 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
429 ourstatus
->set_stopped (GDB_SIGNAL_FPE
);
431 case EXCEPTION_BREAKPOINT
:
433 if (ignore_first_breakpoint
)
435 /* For WOW64 processes, there are always 2 breakpoint exceptions
436 on startup, first a BREAKPOINT for the 64bit ntdll.dll,
437 then a WX86_BREAKPOINT for the 32bit ntdll.dll.
438 Here we only care about the WX86_BREAKPOINT's. */
439 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT - ignore_first_breakpoint");
440 ourstatus
->set_spurious ();
441 ignore_first_breakpoint
= false;
444 else if (wow64_process
)
446 /* This breakpoint exception is triggered for WOW64 processes when
447 reaching an int3 instruction in 64bit code.
448 gdb checks for int3 in case of SIGTRAP, this fails because
449 Wow64GetThreadContext can only report the pc of 32bit code, and
450 gdb lets the target process continue.
451 So handle it as SIGINT instead, then the target is stopped
453 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT - wow64_process");
454 rec
->ExceptionCode
= DBG_CONTROL_C
;
455 ourstatus
->set_stopped (GDB_SIGNAL_INT
);
460 case STATUS_WX86_BREAKPOINT
:
461 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
462 ourstatus
->set_stopped (GDB_SIGNAL_TRAP
);
465 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
466 ourstatus
->set_stopped (GDB_SIGNAL_INT
);
468 case DBG_CONTROL_BREAK
:
469 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
470 ourstatus
->set_stopped (GDB_SIGNAL_INT
);
472 case EXCEPTION_SINGLE_STEP
:
473 case STATUS_WX86_SINGLE_STEP
:
474 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
475 ourstatus
->set_stopped (GDB_SIGNAL_TRAP
);
477 case EXCEPTION_ILLEGAL_INSTRUCTION
:
478 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
479 ourstatus
->set_stopped (GDB_SIGNAL_ILL
);
481 case EXCEPTION_PRIV_INSTRUCTION
:
482 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
483 ourstatus
->set_stopped (GDB_SIGNAL_ILL
);
485 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
486 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
487 ourstatus
->set_stopped (GDB_SIGNAL_ILL
);
489 case MS_VC_EXCEPTION
:
490 DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
491 if (handle_ms_vc_exception (rec
))
493 ourstatus
->set_stopped (GDB_SIGNAL_TRAP
);
494 result
= HANDLE_EXCEPTION_IGNORED
;
497 /* treat improperly formed exception as unknown */
500 /* Treat unhandled first chance exceptions specially. */
501 if (current_event
.u
.Exception
.dwFirstChance
)
502 return HANDLE_EXCEPTION_UNHANDLED
;
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
)
512 last_sig
= ourstatus
->sig ();
516 #undef DEBUG_EXCEPTION_SIMPLE
519 /* See nat/windows-nat.h. */
522 windows_process_info::add_dll (LPVOID load_addr
)
524 HMODULE dummy_hmodule
;
532 if (EnumProcessModulesEx (handle
, &dummy_hmodule
,
533 sizeof (HMODULE
), &cb_needed
,
534 LIST_MODULES_32BIT
) == 0)
540 if (EnumProcessModules (handle
, &dummy_hmodule
,
541 sizeof (HMODULE
), &cb_needed
) == 0)
548 hmodules
= (HMODULE
*) alloca (cb_needed
);
552 if (EnumProcessModulesEx (handle
, hmodules
,
553 cb_needed
, &cb_needed
,
554 LIST_MODULES_32BIT
) == 0)
560 if (EnumProcessModules (handle
, hmodules
,
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;
573 /* This fails on 32bit Windows because it has no SysWOW64 directory,
574 and in this case a path conversion isn't necessary. */
575 UINT len
= GetSystemWow64DirectoryA (syswow_dir
, sizeof (syswow_dir
));
578 /* Check that we have passed a large enough buffer. */
579 gdb_assert (len
< sizeof (syswow_dir
));
581 len
= GetSystemDirectoryA (system_dir
, sizeof (system_dir
));
583 gdb_assert (len
!= 0);
584 /* Check that we have passed a large enough buffer. */
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
];
605 if (GetModuleInformation (handle
, hmodules
[i
],
606 &mi
, sizeof (mi
)) == 0)
609 if (GetModuleFileNameEx (handle
, hmodules
[i
],
610 dll_name
, sizeof (dll_name
)) == 0)
613 wcstombs (dll_name_mb
, dll_name
, MAX_PATH
);
618 /* Convert the DLL path of 32bit processes returned by
619 GetModuleFileNameEx from the 64bit system directory to the
620 32bit syswow64 directory if necessary. */
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();
631 /* Record the DLL if either LOAD_ADDR is NULL or the address
632 at which the DLL was loaded is equal to LOAD_ADDR. */
633 if (!(load_addr
!= nullptr && mi
.lpBaseOfDll
!= load_addr
))
635 handle_load_dll (name
, mi
.lpBaseOfDll
);
636 if (load_addr
!= nullptr)
642 /* See nat/windows-nat.h. */
645 windows_process_info::dll_loaded_event ()
647 gdb_assert (current_event
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
);
649 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
650 const char *dll_name
;
652 /* Try getting the DLL name via the lpImageName field of the event.
653 Note that Microsoft documents this fields as strictly optional,
654 in the sense that it might be NULL. And the first DLL event in
655 particular is explicitly documented as "likely not pass[ed]"
656 (source: MSDN LOAD_DLL_DEBUG_INFO structure). */
657 dll_name
= get_image_name (handle
, event
->lpImageName
, event
->fUnicode
);
658 /* If the DLL name could not be gleaned via lpImageName, try harder
659 by enumerating all the DLLs loaded into the inferior, looking for
660 one that is loaded at base address = lpBaseOfDll. */
661 if (dll_name
!= nullptr)
662 handle_load_dll (dll_name
, event
->lpBaseOfDll
);
663 else if (event
->lpBaseOfDll
!= nullptr)
664 add_dll (event
->lpBaseOfDll
);
667 /* See nat/windows-nat.h. */
670 windows_process_info::add_all_dlls ()
675 /* See nat/windows-nat.h. */
678 windows_process_info::matching_pending_stop (bool debug_events
)
680 /* If there are pending stops, and we might plausibly hit one of
681 them, we don't want to actually continue the inferior -- we just
682 want to report the stop. In this case, we just pretend to
683 continue. See the comment by the definition of "pending_stops"
684 for details on why this is needed. */
685 for (const auto &item
: pending_stops
)
687 if (desired_stop_thread_id
== -1
688 || desired_stop_thread_id
== item
.thread_id
)
690 DEBUG_EVENTS ("pending stop anticipated, desired=0x%x, item=0x%x",
691 desired_stop_thread_id
, item
.thread_id
);
699 /* See nat/windows-nat.h. */
701 gdb::optional
<pending_stop
>
702 windows_process_info::fetch_pending_stop (bool debug_events
)
704 gdb::optional
<pending_stop
> result
;
705 for (auto iter
= pending_stops
.begin ();
706 iter
!= pending_stops
.end ();
709 if (desired_stop_thread_id
== -1
710 || desired_stop_thread_id
== iter
->thread_id
)
713 current_event
= iter
->event
;
715 DEBUG_EVENTS ("pending stop found in 0x%x (desired=0x%x)",
716 iter
->thread_id
, desired_stop_thread_id
);
718 pending_stops
.erase (iter
);
726 /* See nat/windows-nat.h. */
729 continue_last_debug_event (DWORD continue_status
, bool debug_events
)
731 DEBUG_EVENTS ("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
732 (unsigned) last_wait_event
.dwProcessId
,
733 (unsigned) last_wait_event
.dwThreadId
,
734 continue_status
== DBG_CONTINUE
?
735 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED");
737 return ContinueDebugEvent (last_wait_event
.dwProcessId
,
738 last_wait_event
.dwThreadId
,
742 /* See nat/windows-nat.h. */
745 wait_for_debug_event (DEBUG_EVENT
*event
, DWORD timeout
)
747 BOOL result
= WaitForDebugEvent (event
, timeout
);
749 last_wait_event
= *event
;
753 /* Flags to pass to UpdateProcThreadAttribute. */
754 #define relocate_aslr_flags ((0x2 << 8) | (0x2 << 16))
756 /* Attribute to pass to UpdateProcThreadAttribute. */
757 #define mitigation_policy 0x00020007
759 /* Pick one of the symbols as a sentinel. */
760 #ifdef PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
762 static_assert ((PROCESS_CREATION_MITIGATION_POLICY_FORCE_RELOCATE_IMAGES_ALWAYS_OFF
763 | PROCESS_CREATION_MITIGATION_POLICY_BOTTOM_UP_ASLR_ALWAYS_OFF
)
764 == relocate_aslr_flags
,
765 "check that ASLR flag values are correct");
767 static_assert (PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY
== mitigation_policy
,
768 "check that mitigation policy value is correct");
772 /* Helper template for the CreateProcess wrappers.
774 FUNC is the type of the underlying CreateProcess call. CHAR is the
775 character type to use, and INFO is the "startupinfo" type to use.
777 DO_CREATE_PROCESS is the underlying CreateProcess function to use;
778 the remaining arguments are passed to it. */
779 template<typename FUNC
, typename CHAR
, typename INFO
>
781 create_process_wrapper (FUNC
*do_create_process
, const CHAR
*image
,
782 CHAR
*command_line
, DWORD flags
,
783 void *environment
, const CHAR
*cur_dir
,
784 bool no_randomization
,
786 PROCESS_INFORMATION
*process_info
)
788 if (no_randomization
&& disable_randomization_available ())
790 static bool tried_and_failed
;
792 if (!tried_and_failed
)
794 /* Windows 8 is required for the real declaration, but to
795 allow building on earlier versions of Windows, we declare
797 struct gdb_extended_info
800 gdb_lpproc_thread_attribute_list lpAttributeList
;
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
);
813 /* Ignore the result here. The documentation says the first
814 call always fails, by design. */
815 InitializeProcThreadAttributeList (nullptr, 1, 0, &size
);
816 info_ex
.lpAttributeList
817 = (gdb_lpproc_thread_attribute_list
) alloca (size
);
818 InitializeProcThreadAttributeList (info_ex
.lpAttributeList
,
821 gdb::optional
<BOOL
> return_value
;
822 DWORD attr_flags
= relocate_aslr_flags
;
823 if (!UpdateProcThreadAttribute (info_ex
.lpAttributeList
, 0,
828 tried_and_failed
= true;
831 BOOL result
= do_create_process (image
, command_line
,
835 | EXTENDED_STARTUPINFO_PRESENT
),
838 &info_ex
.StartupInfo
,
841 return_value
= result
;
842 else if (GetLastError () == ERROR_INVALID_PARAMETER
)
843 tried_and_failed
= true;
845 return_value
= FALSE
;
848 DeleteProcThreadAttributeList (info_ex
.lpAttributeList
);
850 if (return_value
.has_value ())
851 return *return_value
;
855 return do_create_process (image
,
856 command_line
, /* command line */
857 nullptr, /* Security */
858 nullptr, /* thread */
859 TRUE
, /* inherit handles */
860 flags
, /* start flags */
861 environment
, /* environment */
862 cur_dir
, /* current directory */
867 /* See nat/windows-nat.h. */
870 create_process (const char *image
, char *command_line
, DWORD flags
,
871 void *environment
, const char *cur_dir
,
872 bool no_randomization
,
873 STARTUPINFOA
*startup_info
,
874 PROCESS_INFORMATION
*process_info
)
876 return create_process_wrapper (CreateProcessA
, image
, command_line
, flags
,
877 environment
, cur_dir
, no_randomization
,
878 startup_info
, process_info
);
883 /* See nat/windows-nat.h. */
886 create_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
)
892 return create_process_wrapper (CreateProcessW
, image
, command_line
, flags
,
893 environment
, cur_dir
, no_randomization
,
894 startup_info
, process_info
);
897 #endif /* __CYGWIN__ */
899 /* Define dummy functions which always return error for the rare cases where
900 these functions could not be found. */
901 template<typename
... T
>
908 template<typename
... T
>
916 bad_GetCurrentConsoleFont (HANDLE w
, BOOL bMaxWindow
, CONSOLE_FONT_INFO
*f
)
923 bad_GetConsoleFontSize (HANDLE w
, DWORD nFont
)
931 /* See windows-nat.h. */
934 disable_randomization_available ()
936 return (InitializeProcThreadAttributeList
!= nullptr
937 && UpdateProcThreadAttribute
!= nullptr
938 && DeleteProcThreadAttributeList
!= nullptr);
941 /* See windows-nat.h. */
944 initialize_loadable ()
949 #define GPA(m, func) \
950 func = (func ## _ftype *) GetProcAddress (m, #func)
952 hm
= LoadLibrary (TEXT ("kernel32.dll"));
955 GPA (hm
, DebugActiveProcessStop
);
956 GPA (hm
, DebugBreakProcess
);
957 GPA (hm
, DebugSetProcessKillOnExit
);
958 GPA (hm
, GetConsoleFontSize
);
959 GPA (hm
, DebugActiveProcessStop
);
960 GPA (hm
, GetCurrentConsoleFont
);
962 GPA (hm
, Wow64SuspendThread
);
963 GPA (hm
, Wow64GetThreadContext
);
964 GPA (hm
, Wow64SetThreadContext
);
965 GPA (hm
, Wow64GetThreadSelectorEntry
);
967 GPA (hm
, GenerateConsoleCtrlEvent
);
968 GPA (hm
, GetThreadDescription
);
970 GPA (hm
, InitializeProcThreadAttributeList
);
971 GPA (hm
, UpdateProcThreadAttribute
);
972 GPA (hm
, DeleteProcThreadAttributeList
);
975 /* Set variables to dummy versions of these processes if the function
976 wasn't found in kernel32.dll. */
977 if (!DebugBreakProcess
)
978 DebugBreakProcess
= bad
;
979 if (!DebugActiveProcessStop
|| !DebugSetProcessKillOnExit
)
981 DebugActiveProcessStop
= bad
;
982 DebugSetProcessKillOnExit
= bad
;
984 if (!GetConsoleFontSize
)
985 GetConsoleFontSize
= bad_GetConsoleFontSize
;
986 if (!GetCurrentConsoleFont
)
987 GetCurrentConsoleFont
= bad_GetCurrentConsoleFont
;
989 /* Load optional functions used for retrieving filename information
990 associated with the currently debugged process or its dlls. */
991 hm
= LoadLibrary (TEXT ("psapi.dll"));
994 GPA (hm
, EnumProcessModules
);
996 GPA (hm
, EnumProcessModulesEx
);
998 GPA (hm
, GetModuleInformation
);
999 GPA (hm
, GetModuleFileNameExA
);
1000 GPA (hm
, GetModuleFileNameExW
);
1003 if (!EnumProcessModules
|| !GetModuleInformation
1004 || !GetModuleFileNameExA
|| !GetModuleFileNameExW
)
1006 /* Set variables to dummy versions of these processes if the function
1007 wasn't found in psapi.dll. */
1008 EnumProcessModules
= bad
;
1009 GetModuleInformation
= bad
;
1010 GetModuleFileNameExA
= bad
;
1011 GetModuleFileNameExW
= bad
;
1016 hm
= LoadLibrary (TEXT ("advapi32.dll"));
1019 GPA (hm
, OpenProcessToken
);
1020 GPA (hm
, LookupPrivilegeValueA
);
1021 GPA (hm
, AdjustTokenPrivileges
);
1022 /* Only need to set one of these since if OpenProcessToken fails nothing
1024 if (!OpenProcessToken
|| !LookupPrivilegeValueA
1025 || !AdjustTokenPrivileges
)
1026 OpenProcessToken
= bad
;
1029 /* On some versions of Windows, this function is only available in
1030 KernelBase.dll, not kernel32.dll. */
1031 if (GetThreadDescription
== nullptr)
1033 hm
= LoadLibrary (TEXT ("KernelBase.dll"));
1035 GPA (hm
, GetThreadDescription
);