GDB (xrefs)
/tmp/gdb-7.10/gdb/mingw-hdep.c
Go to the documentation of this file.
1 /* Host support routines for MinGW, for GDB, the GNU debugger.
2 
3  Copyright (C) 2006-2015 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "main.h"
22 #include "serial.h"
23 #include "event-loop.h"
24 
25 #include "gdb_select.h"
26 #include "readline/readline.h"
27 
28 #include <windows.h>
29 
30 /* This event is signalled whenever an asynchronous SIGINT handler
31  needs to perform an action in the main thread. */
32 static HANDLE sigint_event;
33 
34 /* When SIGINT_EVENT is signalled, gdb_select will call this
35  function. */
37 
38 /* Return an absolute file name of the running GDB, if possible, or
39  ARGV0 if not. The return value is in malloc'ed storage. */
40 
41 char *
42 windows_get_absolute_argv0 (const char *argv0)
43 {
44  char full_name[PATH_MAX];
45 
46  if (GetModuleFileName (NULL, full_name, PATH_MAX))
47  return xstrdup (full_name);
48  return xstrdup (argv0);
49 }
50 
51 /* Wrapper for select. On Windows systems, where the select interface
52  only works for sockets, this uses the GDB serial abstraction to
53  handle sockets, consoles, pipes, and serial ports.
54 
55  The arguments to this function are the same as the traditional
56  arguments to select on POSIX platforms. */
57 
58 int
59 gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
60  struct timeval *timeout)
61 {
62  static HANDLE never_handle;
63  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
64  HANDLE h;
65  DWORD event;
66  DWORD num_handles;
67  /* SCBS contains serial control objects corresponding to file
68  descriptors in READFDS and WRITEFDS. */
69  struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
70  /* The number of valid entries in SCBS. */
71  size_t num_scbs;
72  int fd;
73  int num_ready;
74  size_t indx;
75 
76  num_ready = 0;
77  num_handles = 0;
78  num_scbs = 0;
79  for (fd = 0; fd < n; ++fd)
80  {
81  HANDLE read = NULL, except = NULL;
82  struct serial *scb;
83 
84  /* There is no support yet for WRITEFDS. At present, this isn't
85  used by GDB -- but we do not want to silently ignore WRITEFDS
86  if something starts using it. */
87  gdb_assert (!writefds || !FD_ISSET (fd, writefds));
88 
89  if ((!readfds || !FD_ISSET (fd, readfds))
90  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
91  continue;
92 
93  scb = serial_for_fd (fd);
94  if (scb)
95  {
96  serial_wait_handle (scb, &read, &except);
97  scbs[num_scbs++] = scb;
98  }
99 
100  if (read == NULL)
101  read = (HANDLE) _get_osfhandle (fd);
102  if (except == NULL)
103  {
104  if (!never_handle)
105  never_handle = CreateEvent (0, FALSE, FALSE, 0);
106 
107  except = never_handle;
108  }
109 
110  if (readfds && FD_ISSET (fd, readfds))
111  {
112  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
113  handles[num_handles++] = read;
114  }
115 
116  if (exceptfds && FD_ISSET (fd, exceptfds))
117  {
118  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
119  handles[num_handles++] = except;
120  }
121  }
122 
123  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
124  handles[num_handles++] = sigint_event;
125 
126  event = WaitForMultipleObjects (num_handles,
127  handles,
128  FALSE,
129  timeout
130  ? (timeout->tv_sec * 1000
131  + timeout->tv_usec / 1000)
132  : INFINITE);
133  /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
134  HANDLES included an abandoned mutex. Since GDB doesn't use
135  mutexes, that should never occur. */
136  gdb_assert (!(WAIT_ABANDONED_0 <= event
137  && event < WAIT_ABANDONED_0 + num_handles));
138  /* We no longer need the helper threads to check for activity. */
139  for (indx = 0; indx < num_scbs; ++indx)
140  serial_done_wait_handle (scbs[indx]);
141  if (event == WAIT_FAILED)
142  return -1;
143  if (event == WAIT_TIMEOUT)
144  return 0;
145  /* Run through the READFDS, clearing bits corresponding to descriptors
146  for which input is unavailable. */
147  h = handles[event - WAIT_OBJECT_0];
148  for (fd = 0, indx = 0; fd < n; ++fd)
149  {
150  HANDLE fd_h;
151 
152  if ((!readfds || !FD_ISSET (fd, readfds))
153  && (!exceptfds || !FD_ISSET (fd, exceptfds)))
154  continue;
155 
156  if (readfds && FD_ISSET (fd, readfds))
157  {
158  fd_h = handles[indx++];
159  /* This handle might be ready, even though it wasn't the handle
160  returned by WaitForMultipleObjects. */
161  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
162  FD_CLR (fd, readfds);
163  else
164  num_ready++;
165  }
166 
167  if (exceptfds && FD_ISSET (fd, exceptfds))
168  {
169  fd_h = handles[indx++];
170  /* This handle might be ready, even though it wasn't the handle
171  returned by WaitForMultipleObjects. */
172  if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
173  FD_CLR (fd, exceptfds);
174  else
175  num_ready++;
176  }
177  }
178 
179  /* With multi-threaded SIGINT handling, there is a race between the
180  readline signal handler and GDB. It may still be in
181  rl_prep_terminal in another thread. Do not return until it is
182  done; we can check the state here because we never longjmp from
183  signal handlers on Windows. */
184  while (RL_ISSTATE (RL_STATE_SIGHANDLER))
185  Sleep (1);
186 
187  if (h == sigint_event
188  || WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
189  {
190  if (sigint_handler != NULL)
191  call_async_signal_handler (sigint_handler);
192 
193  if (num_ready == 0)
194  {
195  errno = EINTR;
196  return -1;
197  }
198  }
199 
200  return num_ready;
201 }
202 
203 /* Wrapper for the body of signal handlers. On Windows systems, a
204  SIGINT handler runs in its own thread. We can't longjmp from
205  there, and we shouldn't even prompt the user. Delay HANDLER
206  until the main thread is next in gdb_select. */
207 
208 void
210  int immediate_p)
211 {
212  if (immediate_p)
213  sigint_handler = handler;
214  else
215  {
216  mark_async_signal_handler (handler);
217  sigint_handler = NULL;
218  }
219  SetEvent (sigint_event);
220 }
221 
222 /* -Wmissing-prototypes */
224 
225 void
227 {
228  sigint_event = CreateEvent (0, FALSE, FALSE, 0);
229 }
ssize_t read(int fd, void *buf, size_t count)
Definition: expect-read1.c:26
initialize_file_ftype _initialize_mingw_hdep
int gdb_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
Definition: mingw-hdep.c:59
struct serial * serial_for_fd(int fd)
Definition: serial.c:171
void mark_async_signal_handler(async_signal_handler *async_handler_ptr)
Definition: event-loop.c:906
void call_async_signal_handler(struct async_signal_handler *handler)
Definition: event-loop.c:896
static int timeout
Definition: monitor.c:75
void initialize_file_ftype(void)
Definition: defs.h:281
#define gdb_assert(expr)
Definition: gdb_assert.h:33
Definition: serial.h:227
void gdb_call_async_signal_handler(struct async_signal_handler *handler, int immediate_p)
Definition: mingw-hdep.c:209
struct async_signal_handler * sigint_handler
Definition: mingw-hdep.c:36
int fd
Definition: serial.h:233
char * windows_get_absolute_argv0(const char *argv0)
Definition: mingw-hdep.c:42
static HANDLE sigint_event
Definition: mingw-hdep.c:32