OSDN Git Service

PR 11123
[pf3gnuchains/pf3gnuchains3x.git] / gdb / mingw-hdep.c
1 /* Host support routines for MinGW, for GDB, the GNU debugger.
2
3    Copyright (C) 2006, 2007, 2008, 2009, 2010 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 "serial.h"
22 #include "event-loop.h"
23
24 #include "gdb_assert.h"
25 #include "gdb_select.h"
26 #include "gdb_string.h"
27 #include "readline/readline.h"
28
29 #include <windows.h>
30
31 /* This event is signalled whenever an asynchronous SIGINT handler
32    needs to perform an action in the main thread.  */
33 static HANDLE sigint_event;
34
35 /* When SIGINT_EVENT is signalled, gdb_select will call this
36    function.  */
37 struct async_signal_handler *sigint_handler;
38
39 /* The strerror() function can return NULL for errno values that are
40    out of range.  Provide a "safe" version that always returns a
41    printable string.
42
43    The Windows runtime implementation of strerror never returns NULL,
44    but does return a useless string for anything above sys_nerr;
45    unfortunately this includes all socket-related error codes.
46    This replacement tries to find a system-provided error message.  */
47
48 char *
49 safe_strerror (int errnum)
50 {
51   static char *buffer;
52   int len;
53
54   if (errnum >= 0 && errnum < sys_nerr)
55     return strerror (errnum);
56
57   if (buffer)
58     {
59       LocalFree (buffer);
60       buffer = NULL;
61     }
62
63   if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
64                      | FORMAT_MESSAGE_FROM_SYSTEM,
65                      NULL, errnum,
66                      MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
67                      (LPTSTR) &buffer, 0, NULL) == 0)
68     {
69       static char buf[32];
70       xsnprintf (buf, sizeof buf, "(undocumented errno %d)", errnum);
71       return buf;
72     }
73
74   /* Windows error messages end with a period and a CR-LF; strip that
75      out.  */
76   len = strlen (buffer);
77   if (len > 3 && strcmp (buffer + len - 3, ".\r\n") == 0)
78     buffer[len - 3] = '\0';
79
80   return buffer;
81 }
82
83 /* Wrapper for select.  On Windows systems, where the select interface
84    only works for sockets, this uses the GDB serial abstraction to
85    handle sockets, consoles, pipes, and serial ports.
86
87    The arguments to this function are the same as the traditional
88    arguments to select on POSIX platforms.  */
89
90 int
91 gdb_select (int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
92             struct timeval *timeout)
93 {
94   static HANDLE never_handle;
95   HANDLE handles[MAXIMUM_WAIT_OBJECTS];
96   HANDLE h;
97   DWORD event;
98   DWORD num_handles;
99   /* SCBS contains serial control objects corresponding to file
100      descriptors in READFDS and WRITEFDS.  */
101   struct serial *scbs[MAXIMUM_WAIT_OBJECTS];
102   /* The number of valid entries in SCBS.  */
103   size_t num_scbs;
104   int fd;
105   int num_ready;
106   size_t indx;
107
108   num_ready = 0;
109   num_handles = 0;
110   num_scbs = 0;
111   for (fd = 0; fd < n; ++fd)
112     {
113       HANDLE read = NULL, except = NULL;
114       struct serial *scb;
115
116       /* There is no support yet for WRITEFDS.  At present, this isn't
117          used by GDB -- but we do not want to silently ignore WRITEFDS
118          if something starts using it.  */
119       gdb_assert (!writefds || !FD_ISSET (fd, writefds));
120
121       if ((!readfds || !FD_ISSET (fd, readfds))
122           && (!exceptfds || !FD_ISSET (fd, exceptfds)))
123         continue;
124
125       scb = serial_for_fd (fd);
126       if (scb)
127         {
128           serial_wait_handle (scb, &read, &except);
129           scbs[num_scbs++] = scb;
130         }
131
132       if (read == NULL)
133         read = (HANDLE) _get_osfhandle (fd);
134       if (except == NULL)
135         {
136           if (!never_handle)
137             never_handle = CreateEvent (0, FALSE, FALSE, 0);
138
139           except = never_handle;
140         }
141
142       if (readfds && FD_ISSET (fd, readfds))
143         {
144           gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
145           handles[num_handles++] = read;
146         }
147
148       if (exceptfds && FD_ISSET (fd, exceptfds))
149         {
150           gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
151           handles[num_handles++] = except;
152         }
153     }
154
155   gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
156   handles[num_handles++] = sigint_event;
157
158   event = WaitForMultipleObjects (num_handles,
159                                   handles,
160                                   FALSE,
161                                   timeout
162                                   ? (timeout->tv_sec * 1000
163                                      + timeout->tv_usec / 1000)
164                                   : INFINITE);
165   /* EVENT can only be a value in the WAIT_ABANDONED_0 range if the
166      HANDLES included an abandoned mutex.  Since GDB doesn't use
167      mutexes, that should never occur.  */
168   gdb_assert (!(WAIT_ABANDONED_0 <= event
169                 && event < WAIT_ABANDONED_0 + num_handles));
170   /* We no longer need the helper threads to check for activity.  */
171   for (indx = 0; indx < num_scbs; ++indx)
172     serial_done_wait_handle (scbs[indx]);
173   if (event == WAIT_FAILED)
174     return -1;
175   if (event == WAIT_TIMEOUT)
176     return 0;
177   /* Run through the READFDS, clearing bits corresponding to descriptors
178      for which input is unavailable.  */
179   h = handles[event - WAIT_OBJECT_0];
180   for (fd = 0, indx = 0; fd < n; ++fd)
181     {
182       HANDLE fd_h;
183
184       if ((!readfds || !FD_ISSET (fd, readfds))
185           && (!exceptfds || !FD_ISSET (fd, exceptfds)))
186         continue;
187
188       if (readfds && FD_ISSET (fd, readfds))
189         {
190           fd_h = handles[indx++];
191           /* This handle might be ready, even though it wasn't the handle
192              returned by WaitForMultipleObjects.  */
193           if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
194             FD_CLR (fd, readfds);
195           else
196             num_ready++;
197         }
198
199       if (exceptfds && FD_ISSET (fd, exceptfds))
200         {
201           fd_h = handles[indx++];
202           /* This handle might be ready, even though it wasn't the handle
203              returned by WaitForMultipleObjects.  */
204           if (fd_h != h && WaitForSingleObject (fd_h, 0) != WAIT_OBJECT_0)
205             FD_CLR (fd, exceptfds);
206           else
207             num_ready++;
208         }
209     }
210
211   /* With multi-threaded SIGINT handling, there is a race between the
212      readline signal handler and GDB.  It may still be in
213      rl_prep_terminal in another thread.  Do not return until it is
214      done; we can check the state here because we never longjmp from
215      signal handlers on Windows.  */
216   while (RL_ISSTATE (RL_STATE_SIGHANDLER))
217     Sleep (1);
218
219   if (h == sigint_event
220       || WaitForSingleObject (sigint_event, 0) == WAIT_OBJECT_0)
221     {
222       if (sigint_handler != NULL)
223         call_async_signal_handler (sigint_handler);
224
225       if (num_ready == 0)
226         {
227           errno = EINTR;
228           return -1;
229         }
230     }
231
232   return num_ready;
233 }
234
235 /* Wrapper for the body of signal handlers.  On Windows systems, a
236    SIGINT handler runs in its own thread.  We can't longjmp from
237    there, and we shouldn't even prompt the user.  Delay HANDLER
238    until the main thread is next in gdb_select.  */
239
240 void
241 gdb_call_async_signal_handler (struct async_signal_handler *handler,
242                                int immediate_p)
243 {
244   if (immediate_p)
245     sigint_handler = handler;
246   else
247     {
248       mark_async_signal_handler (handler);
249       sigint_handler = NULL;
250     }
251   SetEvent (sigint_event);
252 }
253
254 void
255 _initialize_mingw_hdep (void)
256 {
257   sigint_event = CreateEvent (0, FALSE, FALSE, 0);
258 }