Commit | Line | Data |
---|---|---|
98a03287 TT |
1 | /* Internal interfaces for the Windows code |
2 | Copyright (C) 1995-2019 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 | ||
4834dad0 TT |
22 | namespace windows_nat |
23 | { | |
24 | ||
65bafd5b TT |
25 | windows_thread_info::~windows_thread_info () |
26 | { | |
27 | CloseHandle (h); | |
28 | } | |
29 | ||
98a03287 TT |
30 | void |
31 | windows_thread_info::suspend () | |
32 | { | |
33 | if (suspended != 0) | |
34 | return; | |
35 | ||
36 | if (SuspendThread (h) == (DWORD) -1) | |
37 | { | |
38 | DWORD err = GetLastError (); | |
39 | ||
40 | /* We get Access Denied (5) when trying to suspend | |
41 | threads that Windows started on behalf of the | |
42 | debuggee, usually when those threads are just | |
43 | about to exit. | |
44 | We can get Invalid Handle (6) if the main thread | |
45 | has exited. */ | |
46 | if (err != ERROR_INVALID_HANDLE && err != ERROR_ACCESS_DENIED) | |
47 | warning (_("SuspendThread (tid=0x%x) failed. (winerr %u)"), | |
48 | (unsigned) tid, (unsigned) err); | |
49 | suspended = -1; | |
50 | } | |
51 | else | |
52 | suspended = 1; | |
53 | } | |
54 | ||
55 | void | |
56 | windows_thread_info::resume () | |
57 | { | |
58 | if (suspended > 0) | |
59 | { | |
0a4afda3 TT |
60 | stopped_at_software_breakpoint = false; |
61 | ||
98a03287 TT |
62 | if (ResumeThread (h) == (DWORD) -1) |
63 | { | |
64 | DWORD err = GetLastError (); | |
65 | warning (_("warning: ResumeThread (tid=0x%x) failed. (winerr %u)"), | |
66 | (unsigned) tid, (unsigned) err); | |
67 | } | |
68 | } | |
69 | suspended = 0; | |
70 | } | |
4834dad0 | 71 | |
9d8679cc TT |
72 | const char * |
73 | get_image_name (HANDLE h, void *address, int unicode) | |
74 | { | |
75 | #ifdef __CYGWIN__ | |
76 | static char buf[MAX_PATH]; | |
77 | #else | |
78 | static char buf[(2 * MAX_PATH) + 1]; | |
79 | #endif | |
80 | DWORD size = unicode ? sizeof (WCHAR) : sizeof (char); | |
81 | char *address_ptr; | |
82 | int len = 0; | |
83 | char b[2]; | |
84 | SIZE_T done; | |
85 | ||
86 | /* Attempt to read the name of the dll that was detected. | |
87 | This is documented to work only when actively debugging | |
88 | a program. It will not work for attached processes. */ | |
89 | if (address == NULL) | |
90 | return NULL; | |
91 | ||
92 | #ifdef _WIN32_WCE | |
93 | /* Windows CE reports the address of the image name, | |
94 | instead of an address of a pointer into the image name. */ | |
95 | address_ptr = address; | |
96 | #else | |
97 | /* See if we could read the address of a string, and that the | |
98 | address isn't null. */ | |
99 | if (!ReadProcessMemory (h, address, &address_ptr, | |
100 | sizeof (address_ptr), &done) | |
101 | || done != sizeof (address_ptr) | |
102 | || !address_ptr) | |
103 | return NULL; | |
104 | #endif | |
105 | ||
106 | /* Find the length of the string. */ | |
107 | while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done) | |
108 | && (b[0] != 0 || b[size - 1] != 0) && done == size) | |
109 | continue; | |
110 | ||
111 | if (!unicode) | |
112 | ReadProcessMemory (h, address_ptr, buf, len, &done); | |
113 | else | |
114 | { | |
115 | WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR)); | |
116 | ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR), | |
117 | &done); | |
118 | #ifdef __CYGWIN__ | |
119 | wcstombs (buf, unicode_address, MAX_PATH); | |
120 | #else | |
121 | WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf, | |
122 | 0, 0); | |
123 | #endif | |
124 | } | |
125 | ||
126 | return buf; | |
127 | } | |
128 | ||
4834dad0 | 129 | } |