1 /* Host support routines for MinGW, for GDB, the GNU debugger.
3 Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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/>. */
22 #include "event-loop.h"
24 #include "gdb_assert.h"
25 #include "gdb_select.h"
26 #include "gdb_string.h"
27 #include "readline/readline.h"
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
;
35 /* When SIGINT_EVENT is signalled, gdb_select will call this
37 struct async_signal_handler
*sigint_handler
;
39 /* The strerror() function can return NULL for errno values that are
40 out of range. Provide a "safe" version that always returns a
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. */
49 safe_strerror (int errnum
)
54 if (errnum
>= 0 && errnum
< sys_nerr
)
55 return strerror (errnum
);
63 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER
64 | FORMAT_MESSAGE_FROM_SYSTEM
,
66 MAKELANGID (LANG_NEUTRAL
, SUBLANG_DEFAULT
),
67 (LPTSTR
) &buffer
, 0, NULL
) == 0)
70 xsnprintf (buf
, sizeof buf
, "(undocumented errno %d)", errnum
);
74 /* Windows error messages end with a period and a CR-LF; strip that
76 len
= strlen (buffer
);
77 if (len
> 3 && strcmp (buffer
+ len
- 3, ".\r\n") == 0)
78 buffer
[len
- 3] = '\0';
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.
87 The arguments to this function are the same as the traditional
88 arguments to select on POSIX platforms. */
91 gdb_select (int n
, fd_set
*readfds
, fd_set
*writefds
, fd_set
*exceptfds
,
92 struct timeval
*timeout
)
94 static HANDLE never_handle
;
95 HANDLE handles
[MAXIMUM_WAIT_OBJECTS
];
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. */
111 for (fd
= 0; fd
< n
; ++fd
)
113 HANDLE read
= NULL
, except
= NULL
;
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
));
121 if ((!readfds
|| !FD_ISSET (fd
, readfds
))
122 && (!exceptfds
|| !FD_ISSET (fd
, exceptfds
)))
125 scb
= serial_for_fd (fd
);
128 serial_wait_handle (scb
, &read
, &except
);
129 scbs
[num_scbs
++] = scb
;
133 read
= (HANDLE
) _get_osfhandle (fd
);
137 never_handle
= CreateEvent (0, FALSE
, FALSE
, 0);
139 except
= never_handle
;
142 if (readfds
&& FD_ISSET (fd
, readfds
))
144 gdb_assert (num_handles
< MAXIMUM_WAIT_OBJECTS
);
145 handles
[num_handles
++] = read
;
148 if (exceptfds
&& FD_ISSET (fd
, exceptfds
))
150 gdb_assert (num_handles
< MAXIMUM_WAIT_OBJECTS
);
151 handles
[num_handles
++] = except
;
155 gdb_assert (num_handles
< MAXIMUM_WAIT_OBJECTS
);
156 handles
[num_handles
++] = sigint_event
;
158 event
= WaitForMultipleObjects (num_handles
,
162 ? (timeout
->tv_sec
* 1000
163 + timeout
->tv_usec
/ 1000)
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
)
175 if (event
== WAIT_TIMEOUT
)
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
)
184 if ((!readfds
|| !FD_ISSET (fd
, readfds
))
185 && (!exceptfds
|| !FD_ISSET (fd
, exceptfds
)))
188 if (readfds
&& FD_ISSET (fd
, readfds
))
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
);
199 if (exceptfds
&& FD_ISSET (fd
, exceptfds
))
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
);
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
))
219 if (h
== sigint_event
220 || WaitForSingleObject (sigint_event
, 0) == WAIT_OBJECT_0
)
222 if (sigint_handler
!= NULL
)
223 call_async_signal_handler (sigint_handler
);
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. */
241 gdb_call_async_signal_handler (struct async_signal_handler
*handler
,
245 sigint_handler
= handler
;
248 mark_async_signal_handler (handler
);
249 sigint_handler
= NULL
;
251 SetEvent (sigint_event
);
255 _initialize_mingw_hdep (void)
257 sigint_event
= CreateEvent (0, FALSE
, FALSE
, 0);