Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Mark Mitchell <mark@codesourcery.com>
To: gdb-patches@sources.redhat.com
Subject: PATCH: Detect closed file descriptors on Windows
Date: Thu, 12 Jan 2006 00:11:00 -0000	[thread overview]
Message-ID: <200601112147.k0BLlatG000696@sethra.codesourcery.com> (raw)


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 ----


             reply	other threads:[~2006-01-12  0:11 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-01-12  0:11 Mark Mitchell [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200601112147.k0BLlatG000696@sethra.codesourcery.com \
    --to=mark@codesourcery.com \
    --cc=gdb-patches@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox