This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Don't leave GDB wedged when the connection is lost (remote async)


Hello,

If the remote connection is closed abruptly in sync mode, all is fine, GDB is
always poping the remote target now, and leaving things consistent.

However, in async mode, code paths are different, and GDB would be
left badly wedged.

Say the target was in async mode (set target-async 1).  If the current
execution command had been a synchronous command (a regular 'continue', for
example, sync_execution is set), stdin would have been removed from
the event loop (remote_terminal_inferior) -- this is how GDB simulates
synchronous execution in async mode.  Now you kill the stub.

When the remote target detects the serial connection closing, it
pops the target itself (readchar), and then throws an error.  This means that
inf-loop.c:inferior_event_handler would call target_async on the exec
target, which ends up calling tcomplain (calls error), because that method
doesn't make sense for that target.

Since inf-loop.c:inferior_event_handler was throwing without restoring stdin,
the user wouldn't be able to type any other commands.  The only option at
that point would be to kill GDB by some other means.

I've been going back and forth with that so drastic handling
of exceptions in inferior_event_handler.  At some point, we'll
just have to revamp it.

The attached fixes the issue I'm seeing, and has no other
changes, by doing yet some more needed tear down cleaning up in
remote_close (where it belongs).  Tested on x86-pc-linux-gnu native
and against gdbserver sync/async modes and checked in.

-- 
Pedro Alves
2008-11-04  Pedro Alves  <pedro@codesourcery.com>

	* inf-loop.c (inferior_event_handler): On INF_ERROR and
	INF_REG_EVENT throwing, don't call target_async or pop_target.
	Call pop_all_targets_above.
	* remote.c (remote_close): Call remote_terminal_ours.  Don't call
	signal or target_async.

---
 gdb/inf-loop.c |    6 ++----
 gdb/remote.c   |   21 ++++++++++-----------
 2 files changed, 12 insertions(+), 15 deletions(-)

Index: src/gdb/inf-loop.c
===================================================================
--- src.orig/gdb/inf-loop.c	2008-11-04 19:53:34.000000000 +0000
+++ src/gdb/inf-loop.c	2008-11-04 19:53:50.000000000 +0000
@@ -50,8 +50,7 @@ inferior_event_handler (enum inferior_ev
     {
     case INF_ERROR:
       printf_unfiltered (_("error detected from target.\n"));
-      target_async (NULL, 0);
-      pop_target ();
+      pop_all_targets_above (file_stratum, 0);
       discard_all_intermediate_continuations ();
       discard_all_continuations ();
       async_enable_stdin ();
@@ -65,8 +64,7 @@ inferior_event_handler (enum inferior_ev
       if (!catch_errors (fetch_inferior_event_wrapper, 
 			 client_data, "", RETURN_MASK_ALL))
 	{
-	  target_async (NULL, 0);
-	  pop_target ();
+	  pop_all_targets_above (file_stratum, 0);
 	  discard_all_intermediate_continuations ();
 	  discard_all_continuations ();
 	  async_enable_stdin ();
Index: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c	2008-11-04 19:53:34.000000000 +0000
+++ src/gdb/remote.c	2008-11-04 19:53:50.000000000 +0000
@@ -232,6 +232,8 @@ static int peek_stop_reply (ptid_t ptid)
 static void remote_async_inferior_event_handler (gdb_client_data);
 static void remote_async_get_pending_events_handler (gdb_client_data);
 
+static void remote_terminal_ours (void);
+
 /* The non-stop remote protocol provisions for one pending stop reply.
    This is where we keep it until it is acknowledged.  */
 
@@ -2287,18 +2289,15 @@ extended_remote_restart (void)
 static void
 remote_close (int quitting)
 {
-  if (remote_desc)
-    {
-      /* Unregister the file descriptor from the event loop.  */
-      if (target_is_async_p ())
-	target_async (NULL, 0);
-      serial_close (remote_desc);
-      remote_desc = NULL;
-    }
+  if (remote_desc == NULL)
+    return; /* already closed */
 
-  /* Make sure we don't leave the async SIGINT signal handler
-     installed.  */
-  signal (SIGINT, handle_sigint);
+  /* Make sure we leave stdin registered in the event loop, and we
+     don't leave the async SIGINT signal handler installed.  */
+  remote_terminal_ours ();
+
+  serial_close (remote_desc);
+  remote_desc = NULL;
 
   /* We don't have a connection to the remote stub anymore.  Get rid
      of all the inferiors and their threads we were controlling.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]