Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* PATCH: Detect closed file descriptors on Windows
@ 2006-01-12  0:11 Mark Mitchell
  2006-01-12  0:39 ` Jim Blandy
  0 siblings, 1 reply; 6+ messages in thread
From: Mark Mitchell @ 2006-01-12  0:11 UTC (permalink / raw)
  To: gdb-patches


At present, the gdb_select function (which provides the select
interface on non-Cygwin Windows) never marks a file descriptor as
having experienced an exception; in other words, the third argument to
gdb_select is always the empty set upon return.

The Newlib exit() implementation closes file descriptor zero.  When
GDB is using its built-in simulator, the semi-hosting support maps the
target's file descriptor zero to the host file descriptor zero.  So,
when the target program exits, GDB's standard input goes away.  On
UNIX, GDB notices that because select marks file descriptor zero as
having experienced an exception, and thus, GDB itself exits.  

On Windows, because gdb_select doesn't mark the file descriptor as
having experienced an exception, GDB just runs around calling
gdb_select repeatedly, eating CPU.  (It might be better for GDB to
duplicate descriptor zero, so that GDB's own standard input doesn't go
away, but that's another issue.)  

This patch makes the Windows behavior match the UNIX behavior, by
noticing when get_osfhandle returns INVALID_HANDLE_VALUE.

OK to apply?

--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

2006-01-08  Mark Mitchell  <mark@codesourcery.com>

	* gdb/event-loop.c (gdb_select): Detect file descriptors that have
	been closed.

Index: event-loop.c
===================================================================
RCS file: /cvs/src/src/gdb/event-loop.c,v
retrieving revision 1.26
diff -c -5 -p -r1.26 event-loop.c
*** event-loop.c	25 Apr 2005 23:51:33 -0000	1.26
--- event-loop.c	9 Jan 2006 03:20:55 -0000
*************** gdb_select (int n, fd_set *readfds, fd_s
*** 747,772 ****
    DWORD event;
    DWORD num_handles;
    int fd;
    int num_ready;
  
    num_handles = 0;
    for (fd = 0; fd < n; ++fd)
      {
-       /* EXCEPTFDS is silently ignored.  GDB always sets GDB_EXCEPTION
- 	 when calling add_file_handler, but there is no natural analog
- 	 under Windows.  */
        /* There is no support yet for WRITEFDS.  At present, this isn't
  	 used by GDB -- but we do not want to silently ignore WRITEFDS
  	 if something starts using it.  */
        gdb_assert (!FD_ISSET (fd, writefds));
!       if (FD_ISSET (fd, readfds))
  	{
! 	  gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
! 	  handles[num_handles++] = (HANDLE) _get_osfhandle (fd);
! 	}
!     }
    event = WaitForMultipleObjects (num_handles,
  				  handles,
  				  FALSE,
  				  timeout 
  				  ? (timeout->tv_sec * 1000 + timeout->tv_usec)
--- 747,789 ----
    DWORD event;
    DWORD num_handles;
    int fd;
    int num_ready;
  
+   num_ready = 0;
    num_handles = 0;
    for (fd = 0; fd < n; ++fd)
      {
        /* There is no support yet for WRITEFDS.  At present, this isn't
  	 used by GDB -- but we do not want to silently ignore WRITEFDS
  	 if something starts using it.  */
        gdb_assert (!FD_ISSET (fd, writefds));
!       if (FD_ISSET (fd, readfds) 
! 	  && !FD_ISSET (fd, exceptfds))
! 	continue;
!       h = (HANDLE) _get_osfhandle (fd);
!       if (h == INVALID_HANDLE_VALUE)
  	{
! 	  /* If the underlying handle is INVALID_HANDLE_VALUE, then
! 	     this descriptor is no more.  */
! 	  if (FD_ISSET (fd, exceptfds))
! 	    ++num_ready;
! 	  continue;
! 	}
!       /* The only exceptional condition we recognize is a closed file
! 	 descriptor.  Since we have already checked for that
! 	 condition, clear the exceptional bit for this descriptor.  */
!       FD_CLR (fd, exceptfds);
!       if (FD_ISSET (fd, readfds))
!       {
! 	gdb_assert (num_handles < MAXIMUM_WAIT_OBJECTS);
! 	handles[num_handles++] = h;
!       }
!     }
!   /* If we don't need to wait for any handles, we are done.  */
!   if (!num_handles)
!     return num_ready;
    event = WaitForMultipleObjects (num_handles,
  				  handles,
  				  FALSE,
  				  timeout 
  				  ? (timeout->tv_sec * 1000 + timeout->tv_usec)
*************** gdb_select (int n, fd_set *readfds, fd_s
*** 777,790 ****
    gdb_assert (!(WAIT_ABANDONED_0 <= event
  		&& event < WAIT_ABANDONED_0 + num_handles));
    if (event == WAIT_FAILED)
      return -1;
    if (event == WAIT_TIMEOUT)
!     return 0;
    /* Run through the READFDS, clearing bits corresponding to descriptors
       for which input is unavailable.  */
!   num_ready = num_handles; 
    h = handles[event - WAIT_OBJECT_0];
    for (fd = 0; fd < n; ++fd)
      {
        HANDLE fd_h;
        if (!FD_ISSET (fd, readfds))
--- 794,807 ----
    gdb_assert (!(WAIT_ABANDONED_0 <= event
  		&& event < WAIT_ABANDONED_0 + num_handles));
    if (event == WAIT_FAILED)
      return -1;
    if (event == WAIT_TIMEOUT)
!     return num_ready;
    /* Run through the READFDS, clearing bits corresponding to descriptors
       for which input is unavailable.  */
!   num_ready += num_handles; 
    h = handles[event - WAIT_OBJECT_0];
    for (fd = 0; fd < n; ++fd)
      {
        HANDLE fd_h;
        if (!FD_ISSET (fd, readfds))
*************** gdb_select (int n, fd_set *readfds, fd_s
*** 796,809 ****
  	{
  	  FD_CLR (fd, readfds);
  	  --num_ready;
  	}
      }
-   /* We never report any descriptors available for writing or with
-      exceptional conditions.  */ 
-   FD_ZERO (writefds);
-   FD_ZERO (exceptfds);
  
    return num_ready;
  #else
    return select (n, readfds, writefds, exceptfds, timeout);
  #endif
--- 813,822 ----


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2006-01-14  5:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-12  0:11 PATCH: Detect closed file descriptors on Windows Mark Mitchell
2006-01-12  0:39 ` Jim Blandy
2006-01-12 15:57   ` Mark Mitchell
2006-01-12 20:22     ` Jim Blandy
2006-01-12 20:40       ` Christopher Faylor
2006-01-14  5:14         ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox