1 /* Internal interfaces for the Windows code
2 Copyright (C) 1995-2021 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"
26 HANDLE current_process_handle
;
27 DWORD current_process_id
;
29 enum gdb_signal last_sig
= GDB_SIGNAL_0
;
30 DEBUG_EVENT current_event
;
32 /* The most recent event from WaitForDebugEvent. Unlike
33 current_event, this is guaranteed never to come from a pending
34 stop. This is important because only data from the most recent
35 event from WaitForDebugEvent can be used when calling
36 ContinueDebugEvent. */
37 static DEBUG_EVENT last_wait_event
;
39 DWORD desired_stop_thread_id
= -1;
40 std::vector
<pending_stop
> pending_stops
;
41 EXCEPTION_RECORD siginfo_er
;
44 bool wow64_process
= false;
45 bool ignore_first_breakpoint
= false;
48 AdjustTokenPrivileges_ftype
*AdjustTokenPrivileges
;
49 DebugActiveProcessStop_ftype
*DebugActiveProcessStop
;
50 DebugBreakProcess_ftype
*DebugBreakProcess
;
51 DebugSetProcessKillOnExit_ftype
*DebugSetProcessKillOnExit
;
52 EnumProcessModules_ftype
*EnumProcessModules
;
54 EnumProcessModulesEx_ftype
*EnumProcessModulesEx
;
56 GetModuleInformation_ftype
*GetModuleInformation
;
57 GetModuleFileNameExA_ftype
*GetModuleFileNameExA
;
58 GetModuleFileNameExW_ftype
*GetModuleFileNameExW
;
59 LookupPrivilegeValueA_ftype
*LookupPrivilegeValueA
;
60 OpenProcessToken_ftype
*OpenProcessToken
;
61 GetCurrentConsoleFont_ftype
*GetCurrentConsoleFont
;
62 GetConsoleFontSize_ftype
*GetConsoleFontSize
;
64 Wow64SuspendThread_ftype
*Wow64SuspendThread
;
65 Wow64GetThreadContext_ftype
*Wow64GetThreadContext
;
66 Wow64SetThreadContext_ftype
*Wow64SetThreadContext
;
67 Wow64GetThreadSelectorEntry_ftype
*Wow64GetThreadSelectorEntry
;
69 GenerateConsoleCtrlEvent_ftype
*GenerateConsoleCtrlEvent
;
71 /* Note that 'debug_events' must be locally defined in the relevant
73 #define DEBUG_EVENTS(fmt, ...) \
74 debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
77 windows_thread_info::~windows_thread_info ()
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)"),
99 (unsigned) tid
, (unsigned) 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)"),
117 (unsigned) tid
, (unsigned) err
);
124 get_image_name (HANDLE h
, void *address
, int unicode
)
127 static char buf
[MAX_PATH
];
129 static char buf
[(2 * MAX_PATH
) + 1];
131 DWORD size
= unicode
? sizeof (WCHAR
) : sizeof (char);
137 /* Attempt to read the name of the dll that was detected.
138 This is documented to work only when actively debugging
139 a program. It will not work for attached processes. */
143 /* See if we could read the address of a string, and that the
144 address isn't null. */
145 if (!ReadProcessMemory (h
, address
, &address_ptr
,
146 sizeof (address_ptr
), &done
)
147 || done
!= sizeof (address_ptr
)
151 /* Find the length of the string. */
152 while (ReadProcessMemory (h
, address_ptr
+ len
++ * size
, &b
, size
, &done
)
153 && (b
[0] != 0 || b
[size
- 1] != 0) && done
== size
)
157 ReadProcessMemory (h
, address_ptr
, buf
, len
, &done
);
160 WCHAR
*unicode_address
= (WCHAR
*) alloca (len
* sizeof (WCHAR
));
161 ReadProcessMemory (h
, address_ptr
, unicode_address
, len
* sizeof (WCHAR
),
164 wcstombs (buf
, unicode_address
, MAX_PATH
);
166 WideCharToMultiByte (CP_ACP
, 0, unicode_address
, len
, buf
, sizeof buf
,
174 /* The exception thrown by a program to tell the debugger the name of
175 a thread. The exception record contains an ID of a thread and a
176 name to give it. This exception has no documented name, but MSDN
177 dubs it "MS_VC_EXCEPTION" in one code example. */
178 #define MS_VC_EXCEPTION 0x406d1388
180 handle_exception_result
181 handle_exception (struct target_waitstatus
*ourstatus
, bool debug_exceptions
)
183 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
184 debug_printf ("gdb: Target exception %s at %s\n", x, \
185 host_address_to_string (\
186 current_event.u.Exception.ExceptionRecord.ExceptionAddress))
188 EXCEPTION_RECORD
*rec
= ¤t_event
.u
.Exception
.ExceptionRecord
;
189 DWORD code
= rec
->ExceptionCode
;
190 handle_exception_result result
= HANDLE_EXCEPTION_HANDLED
;
192 memcpy (&siginfo_er
, rec
, sizeof siginfo_er
);
194 ourstatus
->kind
= TARGET_WAITKIND_STOPPED
;
196 /* Record the context of the current thread. */
197 thread_rec (ptid_t (current_event
.dwProcessId
, current_event
.dwThreadId
, 0),
202 case EXCEPTION_ACCESS_VIOLATION
:
203 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
204 ourstatus
->value
.sig
= GDB_SIGNAL_SEGV
;
205 if (handle_access_violation (rec
))
206 return HANDLE_EXCEPTION_UNHANDLED
;
208 case STATUS_STACK_OVERFLOW
:
209 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
210 ourstatus
->value
.sig
= GDB_SIGNAL_SEGV
;
212 case STATUS_FLOAT_DENORMAL_OPERAND
:
213 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
214 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
216 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED
:
217 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
218 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
220 case STATUS_FLOAT_INEXACT_RESULT
:
221 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
222 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
224 case STATUS_FLOAT_INVALID_OPERATION
:
225 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
226 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
228 case STATUS_FLOAT_OVERFLOW
:
229 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
230 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
232 case STATUS_FLOAT_STACK_CHECK
:
233 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
234 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
236 case STATUS_FLOAT_UNDERFLOW
:
237 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
238 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
240 case STATUS_FLOAT_DIVIDE_BY_ZERO
:
241 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
242 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
244 case STATUS_INTEGER_DIVIDE_BY_ZERO
:
245 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
246 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
248 case STATUS_INTEGER_OVERFLOW
:
249 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
250 ourstatus
->value
.sig
= GDB_SIGNAL_FPE
;
252 case EXCEPTION_BREAKPOINT
:
254 if (ignore_first_breakpoint
)
256 /* For WOW64 processes, there are always 2 breakpoint exceptions
257 on startup, first a BREAKPOINT for the 64bit ntdll.dll,
258 then a WX86_BREAKPOINT for the 32bit ntdll.dll.
259 Here we only care about the WX86_BREAKPOINT's. */
260 ourstatus
->kind
= TARGET_WAITKIND_SPURIOUS
;
261 ignore_first_breakpoint
= false;
263 else if (wow64_process
)
265 /* This breakpoint exception is triggered for WOW64 processes when
266 reaching an int3 instruction in 64bit code.
267 gdb checks for int3 in case of SIGTRAP, this fails because
268 Wow64GetThreadContext can only report the pc of 32bit code, and
269 gdb lets the target process continue.
270 So handle it as SIGINT instead, then the target is stopped
272 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
273 rec
->ExceptionCode
= DBG_CONTROL_C
;
274 ourstatus
->value
.sig
= GDB_SIGNAL_INT
;
279 case STATUS_WX86_BREAKPOINT
:
280 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
281 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
284 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
285 ourstatus
->value
.sig
= GDB_SIGNAL_INT
;
287 case DBG_CONTROL_BREAK
:
288 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
289 ourstatus
->value
.sig
= GDB_SIGNAL_INT
;
291 case EXCEPTION_SINGLE_STEP
:
292 case STATUS_WX86_SINGLE_STEP
:
293 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
294 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
296 case EXCEPTION_ILLEGAL_INSTRUCTION
:
297 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
298 ourstatus
->value
.sig
= GDB_SIGNAL_ILL
;
300 case EXCEPTION_PRIV_INSTRUCTION
:
301 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
302 ourstatus
->value
.sig
= GDB_SIGNAL_ILL
;
304 case EXCEPTION_NONCONTINUABLE_EXCEPTION
:
305 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
306 ourstatus
->value
.sig
= GDB_SIGNAL_ILL
;
308 case MS_VC_EXCEPTION
:
309 DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
310 if (handle_ms_vc_exception (rec
))
312 ourstatus
->value
.sig
= GDB_SIGNAL_TRAP
;
313 result
= HANDLE_EXCEPTION_IGNORED
;
316 /* treat improperly formed exception as unknown */
319 /* Treat unhandled first chance exceptions specially. */
320 if (current_event
.u
.Exception
.dwFirstChance
)
321 return HANDLE_EXCEPTION_UNHANDLED
;
322 debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
323 (unsigned) current_event
.u
.Exception
.ExceptionRecord
.ExceptionCode
,
324 host_address_to_string (
325 current_event
.u
.Exception
.ExceptionRecord
.ExceptionAddress
));
326 ourstatus
->value
.sig
= GDB_SIGNAL_UNKNOWN
;
330 last_sig
= ourstatus
->value
.sig
;
333 #undef DEBUG_EXCEPTION_SIMPLE
336 /* Iterate over all DLLs currently mapped by our inferior, looking for
337 a DLL which is loaded at LOAD_ADDR. If found, add the DLL to our
338 list of solibs; otherwise do nothing. LOAD_ADDR NULL means add all
339 DLLs to the list of solibs; this is used when the inferior finishes
340 its initialization, and all the DLLs it statically depends on are
344 windows_add_dll (LPVOID load_addr
)
346 HMODULE dummy_hmodule
;
354 if (EnumProcessModulesEx (current_process_handle
, &dummy_hmodule
,
355 sizeof (HMODULE
), &cb_needed
,
356 LIST_MODULES_32BIT
) == 0)
362 if (EnumProcessModules (current_process_handle
, &dummy_hmodule
,
363 sizeof (HMODULE
), &cb_needed
) == 0)
370 hmodules
= (HMODULE
*) alloca (cb_needed
);
374 if (EnumProcessModulesEx (current_process_handle
, hmodules
,
375 cb_needed
, &cb_needed
,
376 LIST_MODULES_32BIT
) == 0)
382 if (EnumProcessModules (current_process_handle
, hmodules
,
383 cb_needed
, &cb_needed
) == 0)
387 char system_dir
[MAX_PATH
];
388 char syswow_dir
[MAX_PATH
];
389 size_t system_dir_len
= 0;
390 bool convert_syswow_dir
= false;
395 /* This fails on 32bit Windows because it has no SysWOW64 directory,
396 and in this case a path conversion isn't necessary. */
397 UINT len
= GetSystemWow64DirectoryA (syswow_dir
, sizeof (syswow_dir
));
400 /* Check that we have passed a large enough buffer. */
401 gdb_assert (len
< sizeof (syswow_dir
));
403 len
= GetSystemDirectoryA (system_dir
, sizeof (system_dir
));
405 gdb_assert (len
!= 0);
406 /* Check that we have passed a large enough buffer. */
407 gdb_assert (len
< sizeof (system_dir
));
409 strcat (system_dir
, "\\");
410 strcat (syswow_dir
, "\\");
411 system_dir_len
= strlen (system_dir
);
413 convert_syswow_dir
= true;
417 for (i
= 1; i
< (int) (cb_needed
/ sizeof (HMODULE
)); i
++)
421 wchar_t dll_name
[MAX_PATH
];
422 char dll_name_mb
[MAX_PATH
];
424 char dll_name
[MAX_PATH
];
427 if (GetModuleInformation (current_process_handle
, hmodules
[i
],
428 &mi
, sizeof (mi
)) == 0)
431 if (GetModuleFileNameEx (current_process_handle
, hmodules
[i
],
432 dll_name
, sizeof (dll_name
)) == 0)
435 wcstombs (dll_name_mb
, dll_name
, MAX_PATH
);
440 /* Convert the DLL path of 32bit processes returned by
441 GetModuleFileNameEx from the 64bit system directory to the
442 32bit syswow64 directory if necessary. */
443 std::string syswow_dll_path
;
444 if (convert_syswow_dir
445 && strncasecmp (name
, system_dir
, system_dir_len
) == 0
446 && strchr (name
+ system_dir_len
, '\\') == nullptr)
448 syswow_dll_path
= syswow_dir
;
449 syswow_dll_path
+= name
+ system_dir_len
;
450 name
= syswow_dll_path
.c_str();
453 /* Record the DLL if either LOAD_ADDR is NULL or the address
454 at which the DLL was loaded is equal to LOAD_ADDR. */
455 if (!(load_addr
!= nullptr && mi
.lpBaseOfDll
!= load_addr
))
457 handle_load_dll (name
, mi
.lpBaseOfDll
);
458 if (load_addr
!= nullptr)
464 /* See nat/windows-nat.h. */
469 gdb_assert (current_event
.dwDebugEventCode
== LOAD_DLL_DEBUG_EVENT
);
471 LOAD_DLL_DEBUG_INFO
*event
= ¤t_event
.u
.LoadDll
;
472 const char *dll_name
;
474 /* Try getting the DLL name via the lpImageName field of the event.
475 Note that Microsoft documents this fields as strictly optional,
476 in the sense that it might be NULL. And the first DLL event in
477 particular is explicitly documented as "likely not pass[ed]"
478 (source: MSDN LOAD_DLL_DEBUG_INFO structure). */
479 dll_name
= get_image_name (current_process_handle
,
480 event
->lpImageName
, event
->fUnicode
);
481 /* If the DLL name could not be gleaned via lpImageName, try harder
482 by enumerating all the DLLs loaded into the inferior, looking for
483 one that is loaded at base address = lpBaseOfDll. */
484 if (dll_name
!= nullptr)
485 handle_load_dll (dll_name
, event
->lpBaseOfDll
);
486 else if (event
->lpBaseOfDll
!= nullptr)
487 windows_add_dll (event
->lpBaseOfDll
);
490 /* See nat/windows-nat.h. */
493 windows_add_all_dlls ()
495 windows_add_dll (nullptr);
498 /* See nat/windows-nat.h. */
501 matching_pending_stop (bool debug_events
)
503 /* If there are pending stops, and we might plausibly hit one of
504 them, we don't want to actually continue the inferior -- we just
505 want to report the stop. In this case, we just pretend to
506 continue. See the comment by the definition of "pending_stops"
507 for details on why this is needed. */
508 for (const auto &item
: pending_stops
)
510 if (desired_stop_thread_id
== -1
511 || desired_stop_thread_id
== item
.thread_id
)
513 DEBUG_EVENTS ("pending stop anticipated, desired=0x%x, item=0x%x",
514 desired_stop_thread_id
, item
.thread_id
);
522 /* See nat/windows-nat.h. */
524 gdb::optional
<pending_stop
>
525 fetch_pending_stop (bool debug_events
)
527 gdb::optional
<pending_stop
> result
;
528 for (auto iter
= pending_stops
.begin ();
529 iter
!= pending_stops
.end ();
532 if (desired_stop_thread_id
== -1
533 || desired_stop_thread_id
== iter
->thread_id
)
536 current_event
= iter
->event
;
538 DEBUG_EVENTS ("pending stop found in 0x%x (desired=0x%x)",
539 iter
->thread_id
, desired_stop_thread_id
);
541 pending_stops
.erase (iter
);
549 /* See nat/windows-nat.h. */
552 continue_last_debug_event (DWORD continue_status
, bool debug_events
)
554 DEBUG_EVENTS ("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
555 (unsigned) last_wait_event
.dwProcessId
,
556 (unsigned) last_wait_event
.dwThreadId
,
557 continue_status
== DBG_CONTINUE
?
558 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED");
560 return ContinueDebugEvent (last_wait_event
.dwProcessId
,
561 last_wait_event
.dwThreadId
,
565 /* See nat/windows-nat.h. */
568 wait_for_debug_event (DEBUG_EVENT
*event
, DWORD timeout
)
570 BOOL result
= WaitForDebugEvent (event
, timeout
);
572 last_wait_event
= *event
;
576 /* Define dummy functions which always return error for the rare cases where
577 these functions could not be found. */
578 template<typename
... T
>
585 template<typename
... T
>
593 bad_GetCurrentConsoleFont (HANDLE w
, BOOL bMaxWindow
, CONSOLE_FONT_INFO
*f
)
600 bad_GetConsoleFontSize (HANDLE w
, DWORD nFont
)
608 /* See windows-nat.h. */
611 initialize_loadable ()
616 #define GPA(m, func) \
617 func = (func ## _ftype *) GetProcAddress (m, #func)
619 hm
= LoadLibrary (TEXT ("kernel32.dll"));
622 GPA (hm
, DebugActiveProcessStop
);
623 GPA (hm
, DebugBreakProcess
);
624 GPA (hm
, DebugSetProcessKillOnExit
);
625 GPA (hm
, GetConsoleFontSize
);
626 GPA (hm
, DebugActiveProcessStop
);
627 GPA (hm
, GetCurrentConsoleFont
);
629 GPA (hm
, Wow64SuspendThread
);
630 GPA (hm
, Wow64GetThreadContext
);
631 GPA (hm
, Wow64SetThreadContext
);
632 GPA (hm
, Wow64GetThreadSelectorEntry
);
634 GPA (hm
, GenerateConsoleCtrlEvent
);
637 /* Set variables to dummy versions of these processes if the function
638 wasn't found in kernel32.dll. */
639 if (!DebugBreakProcess
)
640 DebugBreakProcess
= bad
;
641 if (!DebugActiveProcessStop
|| !DebugSetProcessKillOnExit
)
643 DebugActiveProcessStop
= bad
;
644 DebugSetProcessKillOnExit
= bad
;
646 if (!GetConsoleFontSize
)
647 GetConsoleFontSize
= bad_GetConsoleFontSize
;
648 if (!GetCurrentConsoleFont
)
649 GetCurrentConsoleFont
= bad_GetCurrentConsoleFont
;
651 /* Load optional functions used for retrieving filename information
652 associated with the currently debugged process or its dlls. */
653 hm
= LoadLibrary (TEXT ("psapi.dll"));
656 GPA (hm
, EnumProcessModules
);
658 GPA (hm
, EnumProcessModulesEx
);
660 GPA (hm
, GetModuleInformation
);
661 GPA (hm
, GetModuleFileNameExA
);
662 GPA (hm
, GetModuleFileNameExW
);
665 if (!EnumProcessModules
|| !GetModuleInformation
666 || !GetModuleFileNameExA
|| !GetModuleFileNameExW
)
668 /* Set variables to dummy versions of these processes if the function
669 wasn't found in psapi.dll. */
670 EnumProcessModules
= bad
;
671 GetModuleInformation
= bad
;
672 GetModuleFileNameExA
= bad
;
673 GetModuleFileNameExW
= bad
;
678 hm
= LoadLibrary (TEXT ("advapi32.dll"));
681 GPA (hm
, OpenProcessToken
);
682 GPA (hm
, LookupPrivilegeValueA
);
683 GPA (hm
, AdjustTokenPrivileges
);
684 /* Only need to set one of these since if OpenProcessToken fails nothing
686 if (!OpenProcessToken
|| !LookupPrivilegeValueA
687 || !AdjustTokenPrivileges
)
688 OpenProcessToken
= bad
;