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