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