Use debug_prefixed_printf_cond in windows-nat.c
[deliverable/binutils-gdb.git] / gdb / nat / windows-nat.c
1 /* Internal interfaces for the Windows code
2 Copyright (C) 1995-2021 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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/>. */
18
19 #include "gdbsupport/common-defs.h"
20 #include "nat/windows-nat.h"
21 #include "gdbsupport/common-debug.h"
22
23 namespace windows_nat
24 {
25
26 HANDLE current_process_handle;
27 DWORD current_process_id;
28 DWORD main_thread_id;
29 enum gdb_signal last_sig = GDB_SIGNAL_0;
30 DEBUG_EVENT current_event;
31
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;
38
39 DWORD desired_stop_thread_id = -1;
40 std::vector<pending_stop> pending_stops;
41 EXCEPTION_RECORD siginfo_er;
42
43 #ifdef __x86_64__
44 bool wow64_process = false;
45 bool ignore_first_breakpoint = false;
46 #endif
47
48 /* Note that 'debug_events' must be locally defined in the relevant
49 functions. */
50 #define DEBUG_EVENTS(fmt, ...) \
51 debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
52 ## __VA_ARGS__)
53
54 windows_thread_info::~windows_thread_info ()
55 {
56 }
57
58 void
59 windows_thread_info::suspend ()
60 {
61 if (suspended != 0)
62 return;
63
64 if (SuspendThread (h) == (DWORD) -1)
65 {
66 DWORD err = GetLastError ();
67
68 /* We get Access Denied (5) when trying to suspend
69 threads that Windows started on behalf of the
70 debuggee, usually when those threads are just
71 about to exit.
72 We can get Invalid Handle (6) if the main thread
73 has exited. */
74 if (err != ERROR_INVALID_HANDLE && err != ERROR_ACCESS_DENIED)
75 warning (_("SuspendThread (tid=0x%x) failed. (winerr %u)"),
76 (unsigned) tid, (unsigned) err);
77 suspended = -1;
78 }
79 else
80 suspended = 1;
81 }
82
83 void
84 windows_thread_info::resume ()
85 {
86 if (suspended > 0)
87 {
88 stopped_at_software_breakpoint = false;
89
90 if (ResumeThread (h) == (DWORD) -1)
91 {
92 DWORD err = GetLastError ();
93 warning (_("warning: ResumeThread (tid=0x%x) failed. (winerr %u)"),
94 (unsigned) tid, (unsigned) err);
95 }
96 }
97 suspended = 0;
98 }
99
100 const char *
101 get_image_name (HANDLE h, void *address, int unicode)
102 {
103 #ifdef __CYGWIN__
104 static char buf[MAX_PATH];
105 #else
106 static char buf[(2 * MAX_PATH) + 1];
107 #endif
108 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
109 char *address_ptr;
110 int len = 0;
111 char b[2];
112 SIZE_T done;
113
114 /* Attempt to read the name of the dll that was detected.
115 This is documented to work only when actively debugging
116 a program. It will not work for attached processes. */
117 if (address == NULL)
118 return NULL;
119
120 #ifdef _WIN32_WCE
121 /* Windows CE reports the address of the image name,
122 instead of an address of a pointer into the image name. */
123 address_ptr = address;
124 #else
125 /* See if we could read the address of a string, and that the
126 address isn't null. */
127 if (!ReadProcessMemory (h, address, &address_ptr,
128 sizeof (address_ptr), &done)
129 || done != sizeof (address_ptr)
130 || !address_ptr)
131 return NULL;
132 #endif
133
134 /* Find the length of the string. */
135 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
136 && (b[0] != 0 || b[size - 1] != 0) && done == size)
137 continue;
138
139 if (!unicode)
140 ReadProcessMemory (h, address_ptr, buf, len, &done);
141 else
142 {
143 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
144 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
145 &done);
146 #ifdef __CYGWIN__
147 wcstombs (buf, unicode_address, MAX_PATH);
148 #else
149 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
150 0, 0);
151 #endif
152 }
153
154 return buf;
155 }
156
157 /* The exception thrown by a program to tell the debugger the name of
158 a thread. The exception record contains an ID of a thread and a
159 name to give it. This exception has no documented name, but MSDN
160 dubs it "MS_VC_EXCEPTION" in one code example. */
161 #define MS_VC_EXCEPTION 0x406d1388
162
163 handle_exception_result
164 handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
165 {
166 #define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
167 debug_printf ("gdb: Target exception %s at %s\n", x, \
168 host_address_to_string (\
169 current_event.u.Exception.ExceptionRecord.ExceptionAddress))
170
171 EXCEPTION_RECORD *rec = &current_event.u.Exception.ExceptionRecord;
172 DWORD code = rec->ExceptionCode;
173 handle_exception_result result = HANDLE_EXCEPTION_HANDLED;
174
175 memcpy (&siginfo_er, rec, sizeof siginfo_er);
176
177 ourstatus->kind = TARGET_WAITKIND_STOPPED;
178
179 /* Record the context of the current thread. */
180 thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
181 DONT_SUSPEND);
182
183 switch (code)
184 {
185 case EXCEPTION_ACCESS_VIOLATION:
186 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
187 ourstatus->value.sig = GDB_SIGNAL_SEGV;
188 if (handle_access_violation (rec))
189 return HANDLE_EXCEPTION_UNHANDLED;
190 break;
191 case STATUS_STACK_OVERFLOW:
192 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
193 ourstatus->value.sig = GDB_SIGNAL_SEGV;
194 break;
195 case STATUS_FLOAT_DENORMAL_OPERAND:
196 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
197 ourstatus->value.sig = GDB_SIGNAL_FPE;
198 break;
199 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
200 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
201 ourstatus->value.sig = GDB_SIGNAL_FPE;
202 break;
203 case STATUS_FLOAT_INEXACT_RESULT:
204 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
205 ourstatus->value.sig = GDB_SIGNAL_FPE;
206 break;
207 case STATUS_FLOAT_INVALID_OPERATION:
208 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
209 ourstatus->value.sig = GDB_SIGNAL_FPE;
210 break;
211 case STATUS_FLOAT_OVERFLOW:
212 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
213 ourstatus->value.sig = GDB_SIGNAL_FPE;
214 break;
215 case STATUS_FLOAT_STACK_CHECK:
216 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
217 ourstatus->value.sig = GDB_SIGNAL_FPE;
218 break;
219 case STATUS_FLOAT_UNDERFLOW:
220 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
221 ourstatus->value.sig = GDB_SIGNAL_FPE;
222 break;
223 case STATUS_FLOAT_DIVIDE_BY_ZERO:
224 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
225 ourstatus->value.sig = GDB_SIGNAL_FPE;
226 break;
227 case STATUS_INTEGER_DIVIDE_BY_ZERO:
228 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
229 ourstatus->value.sig = GDB_SIGNAL_FPE;
230 break;
231 case STATUS_INTEGER_OVERFLOW:
232 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
233 ourstatus->value.sig = GDB_SIGNAL_FPE;
234 break;
235 case EXCEPTION_BREAKPOINT:
236 #ifdef __x86_64__
237 if (ignore_first_breakpoint)
238 {
239 /* For WOW64 processes, there are always 2 breakpoint exceptions
240 on startup, first a BREAKPOINT for the 64bit ntdll.dll,
241 then a WX86_BREAKPOINT for the 32bit ntdll.dll.
242 Here we only care about the WX86_BREAKPOINT's. */
243 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
244 ignore_first_breakpoint = false;
245 }
246 else if (wow64_process)
247 {
248 /* This breakpoint exception is triggered for WOW64 processes when
249 reaching an int3 instruction in 64bit code.
250 gdb checks for int3 in case of SIGTRAP, this fails because
251 Wow64GetThreadContext can only report the pc of 32bit code, and
252 gdb lets the target process continue.
253 So handle it as SIGINT instead, then the target is stopped
254 unconditionally. */
255 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
256 rec->ExceptionCode = DBG_CONTROL_C;
257 ourstatus->value.sig = GDB_SIGNAL_INT;
258 break;
259 }
260 #endif
261 /* FALLTHROUGH */
262 case STATUS_WX86_BREAKPOINT:
263 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
264 ourstatus->value.sig = GDB_SIGNAL_TRAP;
265 #ifdef _WIN32_WCE
266 /* Remove the initial breakpoint. */
267 check_breakpoints ((CORE_ADDR) (long) current_event
268 .u.Exception.ExceptionRecord.ExceptionAddress);
269 #endif
270 break;
271 case DBG_CONTROL_C:
272 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
273 ourstatus->value.sig = GDB_SIGNAL_INT;
274 break;
275 case DBG_CONTROL_BREAK:
276 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
277 ourstatus->value.sig = GDB_SIGNAL_INT;
278 break;
279 case EXCEPTION_SINGLE_STEP:
280 case STATUS_WX86_SINGLE_STEP:
281 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
282 ourstatus->value.sig = GDB_SIGNAL_TRAP;
283 break;
284 case EXCEPTION_ILLEGAL_INSTRUCTION:
285 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
286 ourstatus->value.sig = GDB_SIGNAL_ILL;
287 break;
288 case EXCEPTION_PRIV_INSTRUCTION:
289 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
290 ourstatus->value.sig = GDB_SIGNAL_ILL;
291 break;
292 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
293 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
294 ourstatus->value.sig = GDB_SIGNAL_ILL;
295 break;
296 case MS_VC_EXCEPTION:
297 DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
298 if (handle_ms_vc_exception (rec))
299 {
300 ourstatus->value.sig = GDB_SIGNAL_TRAP;
301 result = HANDLE_EXCEPTION_IGNORED;
302 break;
303 }
304 /* treat improperly formed exception as unknown */
305 /* FALLTHROUGH */
306 default:
307 /* Treat unhandled first chance exceptions specially. */
308 if (current_event.u.Exception.dwFirstChance)
309 return HANDLE_EXCEPTION_UNHANDLED;
310 debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
311 (unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
312 host_address_to_string (
313 current_event.u.Exception.ExceptionRecord.ExceptionAddress));
314 ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
315 break;
316 }
317
318 last_sig = ourstatus->value.sig;
319 return result;
320
321 #undef DEBUG_EXCEPTION_SIMPLE
322 }
323
324 /* See nat/windows-nat.h. */
325
326 bool
327 matching_pending_stop (bool debug_events)
328 {
329 /* If there are pending stops, and we might plausibly hit one of
330 them, we don't want to actually continue the inferior -- we just
331 want to report the stop. In this case, we just pretend to
332 continue. See the comment by the definition of "pending_stops"
333 for details on why this is needed. */
334 for (const auto &item : pending_stops)
335 {
336 if (desired_stop_thread_id == -1
337 || desired_stop_thread_id == item.thread_id)
338 {
339 DEBUG_EVENTS ("pending stop anticipated, desired=0x%x, item=0x%x",
340 desired_stop_thread_id, item.thread_id);
341 return true;
342 }
343 }
344
345 return false;
346 }
347
348 /* See nat/windows-nat.h. */
349
350 gdb::optional<pending_stop>
351 fetch_pending_stop (bool debug_events)
352 {
353 gdb::optional<pending_stop> result;
354 for (auto iter = pending_stops.begin ();
355 iter != pending_stops.end ();
356 ++iter)
357 {
358 if (desired_stop_thread_id == -1
359 || desired_stop_thread_id == iter->thread_id)
360 {
361 result = *iter;
362 current_event = iter->event;
363
364 DEBUG_EVENTS ("pending stop found in 0x%x (desired=0x%x)",
365 iter->thread_id, desired_stop_thread_id);
366
367 pending_stops.erase (iter);
368 break;
369 }
370 }
371
372 return result;
373 }
374
375 /* See nat/windows-nat.h. */
376
377 BOOL
378 continue_last_debug_event (DWORD continue_status, bool debug_events)
379 {
380 DEBUG_EVENTS ("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
381 (unsigned) last_wait_event.dwProcessId,
382 (unsigned) last_wait_event.dwThreadId,
383 continue_status == DBG_CONTINUE ?
384 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED");
385
386 return ContinueDebugEvent (last_wait_event.dwProcessId,
387 last_wait_event.dwThreadId,
388 continue_status);
389 }
390
391 /* See nat/windows-nat.h. */
392
393 BOOL
394 wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
395 {
396 BOOL result = WaitForDebugEvent (event, timeout);
397 if (result)
398 last_wait_event = *event;
399 return result;
400 }
401
402 }
This page took 0.145777 seconds and 5 git commands to generate.