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