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