public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PING][PATCH] GDB/libiberty: Mingw32 remote debug hang on close
@ 2010-04-19 23:51 Maciej W. Rozycki
  0 siblings, 0 replies; only message in thread
From: Maciej W. Rozycki @ 2010-04-19 23:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: gdb-patches, Maciej W. Rozycki

Hi,

 Would anyone please review the change below?  Thanks.

  Maciej

---------- Forwarded message ----------
Message-ID: <alpine.DEB.1.10.0912181134140.4720@tp.orcam.me.uk>
Date: Wed, 23 Dec 2009 19:25:13 +0000 (GMT)
From: Maciej W. Rozycki <macro@codesourcery.com>
To: gcc-patches@gcc.gnu.org
Cc: gdb-patches@sourceware.org, Maciej W. Rozycki <macro@linux-mips.org>
Subject: [PATCH] GDB/libiberty: Mingw32 remote debug hang on close

Hello,

 Noticed while debugging a remote target using pipes to communicate with a 
debug stub both running on a Mingw32 host.

 When a debug session is terminated from the GDB side, like with:

(gdb) kill

and the stub outputs any data to its stderr file descriptor (such as 
diagnostic information) afterwards before it terminates, then both 
programs hang.

 I have tracked down the cause to be the parent pipe descriptor 
corresponding to child's stderr having been left open while a wait() call 
is made in the parent to await child's termination.  Meanwhile the child 
would keep producing diagnostic output to its stderr up till the 
exhaustion of the pipe system buffer at which point the child would hang 
as the parent busy with the wait() would not pay attention to its 
corresponding descriptor anymore.

 Here's a change that works for me.  It makes sure the parent pipe 
descriptors corresponding to child's stderr and stdout are closed before 
the call to wait() is made, making any writes to these pipes in the child 
fail straight away.

2009-12-23  Maciej W. Rozycki  <macro@codesourcery.com>

	libiberty/
	* pex-common.c (pex_read_err): Set stderr_pipe to -1 if a 
	corresponding stream has been opened.
	(pex_free): Close pipe file descriptors corresponding to child's 
	stdout and stderr before waiting.

 Regression tested successfully with GDB testsuite the i386-mingw32 host 
and the mips-sde-elf target, using QEMU as the remote system.  OK to 
apply?

  Maciej

gdb-6.8.50-20091205-pex-free-0.patch
Index: libiberty/pex-common.c
===================================================================
--- libiberty/pex-common.c	(revision 268718)
+++ libiberty/pex-common.c	(working copy)
@@ -505,6 +505,7 @@ pex_read_err (struct pex_obj *obj, int b
   if (o < 0 || o == STDIN_FILE_NO)
     return NULL;
   obj->read_err = obj->funcs->fdopenr (obj, o, binary);
+  obj->stderr_pipe = -1;
   return obj->read_err;    
 }
 
@@ -597,8 +598,17 @@ pex_get_times (struct pex_obj *obj, int 
 void
 pex_free (struct pex_obj *obj)
 {
+  /* Close pipe file descriptors corresponding to child's stdout and
+     stderr so that the child does not hang trying to output anything
+     while we're waiting for it.  */
   if (obj->next_input >= 0 && obj->next_input != STDIN_FILE_NO)
     obj->funcs->close (obj, obj->next_input);
+  if (obj->stderr_pipe >= 0 && obj->stderr_pipe != STDIN_FILE_NO)
+    obj->funcs->close (obj, obj->stderr_pipe);
+  if (obj->read_output != NULL)
+    fclose (obj->read_output);
+  if (obj->read_err != NULL)
+    fclose (obj->read_err);
 
   /* If the caller forgot to wait for the children, we do it here, to
      avoid zombies.  */
@@ -619,10 +629,6 @@ pex_free (struct pex_obj *obj)
     free (obj->status);
   if (obj->time != NULL)
     free (obj->time);
-  if (obj->read_output != NULL)
-    fclose (obj->read_output);
-  if (obj->read_err != NULL)
-    fclose (obj->read_err);
 
   if (obj->remove_count > 0)
     {

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-04-19 23:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-19 23:51 [PING][PATCH] GDB/libiberty: Mingw32 remote debug hang on close Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).