]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Change serial_readchar to throw
authorTom Tromey <tromey@adacore.com>
Tue, 29 Aug 2023 14:22:09 +0000 (08:22 -0600)
committerTom Tromey <tromey@adacore.com>
Mon, 27 Nov 2023 19:55:14 +0000 (12:55 -0700)
This changes serial_readchar to throw an exception rather than trying
to set and preserve errno.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30770

gdb/remote.c
gdb/ser-mingw.c
gdb/ser-tcp.c
gdb/ser-uds.c
gdb/ser-unix.c

index 49c1c96f1e5c04c91cd52f81e06a95f459ab2a3d..22215b5633fcf2b3044430417e23cee9459cfa13 100644 (file)
@@ -9779,22 +9779,6 @@ remote_target::flash_done ()
 /* Stuff for dealing with the packets which are part of this protocol.
    See comment at top of file for details.  */
 
-/* Close/unpush the remote target, and throw a TARGET_CLOSE_ERROR
-   error to higher layers.  Called when a serial error is detected.
-   The exception message is STRING, followed by a colon and a blank,
-   the system error message for errno at function entry and final dot
-   for output compatibility with throw_perror_with_name.  */
-
-static void
-unpush_and_perror (remote_target *target, const char *string)
-{
-  int saved_errno = errno;
-
-  remote_unpush_target (target);
-  throw_error (TARGET_CLOSE_ERROR, "%s: %s.", string,
-              safe_strerror (saved_errno));
-}
-
 /* Read a single character from the remote end.  The current quit
    handler is overridden to avoid quitting in the middle of packet
    sequence, as that would break communication with the remote server.
@@ -9806,36 +9790,38 @@ remote_target::readchar (int timeout)
   int ch;
   struct remote_state *rs = get_remote_state ();
 
-  {
-    scoped_restore restore_quit_target
-      = make_scoped_restore (&curr_quit_handler_target, this);
-    scoped_restore restore_quit
-      = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
+  try
+    {
+      scoped_restore restore_quit_target
+       = make_scoped_restore (&curr_quit_handler_target, this);
+      scoped_restore restore_quit
+       = make_scoped_restore (&quit_handler, ::remote_serial_quit_handler);
 
-    rs->got_ctrlc_during_io = 0;
+      rs->got_ctrlc_during_io = 0;
 
-    ch = serial_readchar (rs->remote_desc, timeout);
+      ch = serial_readchar (rs->remote_desc, timeout);
 
-    if (rs->got_ctrlc_during_io)
-      set_quit_flag ();
-  }
+      if (rs->got_ctrlc_during_io)
+       set_quit_flag ();
+    }
+  catch (const gdb_exception_error &ex)
+    {
+      remote_unpush_target (this);
+      throw_error (TARGET_CLOSE_ERROR,
+                  _("Remote communication error.  "
+                    "Target disconnected: %s"),
+                  ex.what ());
+    }
 
   if (ch >= 0)
     return ch;
 
-  switch ((enum serial_rc) ch)
+  if (ch == SERIAL_EOF)
     {
-    case SERIAL_EOF:
       remote_unpush_target (this);
       throw_error (TARGET_CLOSE_ERROR, _("Remote connection closed"));
-      /* no return */
-    case SERIAL_ERROR:
-      unpush_and_perror (this, _("Remote communication error.  "
-                                "Target disconnected"));
-      /* no return */
-    case SERIAL_TIMEOUT:
-      break;
     }
+
   return ch;
 }
 
index 4607a10fde87564b49ee405946e6902e575b082c..25016aebee50e64f1d6087e5ed8fcc331081a0a0 100644 (file)
@@ -333,7 +333,11 @@ ser_windows_read_prim (struct serial *scb, size_t count)
     {
       if (GetLastError () != ERROR_IO_PENDING
          || !GetOverlappedResult (h, &ov, &bytes_read, TRUE))
-       bytes_read = -1;
+       {
+         ULONGEST err = GetLastError ();
+         CloseHandle (ov.hEvent);
+         throw_winerror_with_name (_("error while reading"), err);
+       }
     }
 
   CloseHandle (ov.hEvent);
@@ -962,16 +966,16 @@ pipe_windows_read (struct serial *scb, size_t count)
   DWORD bytes_read;
 
   if (pipeline_out == INVALID_HANDLE_VALUE)
-    return -1;
+    error (_("could not find file number for pipe"));
 
   if (! PeekNamedPipe (pipeline_out, NULL, 0, NULL, &available, NULL))
-    return -1;
+    throw_winerror_with_name (_("could not peek into pipe"), GetLastError ());
 
   if (count > available)
     count = available;
 
   if (! ReadFile (pipeline_out, scb->buf, count, &bytes_read, NULL))
-    return -1;
+    throw_winerror_with_name (_("could not read from pipe"), GetLastError ());
 
   return bytes_read;
 }
index ce3c61815d8800c861eaddf1723724a878c6a0cb..cfd1343eced7dac24b68b9c00eb203fb33463e57 100644 (file)
@@ -409,7 +409,10 @@ net_read_prim (struct serial *scb, size_t count)
   /* Need to cast to silence -Wpointer-sign on MinGW, as Winsock's
      'recv' takes 'char *' as second argument, while 'scb->buf' is
      'unsigned char *'.  */
-  return recv (scb->fd, (char *) scb->buf, count, 0);
+  int result = recv (scb->fd, (char *) scb->buf, count, 0);
+  if (result == -1 && errno != EINTR)
+    perror_with_name ("error while reading");
+  return result;
 }
 
 int
index baa660be21d161c1e5c7fa56ac07cbfd706e6951..ad1f79e08002de9ce655a8b36f0b0fb05bff35c6 100644 (file)
@@ -69,7 +69,10 @@ uds_close (struct serial *scb)
 static int
 uds_read_prim (struct serial *scb, size_t count)
 {
-  return recv (scb->fd, scb->buf, count, 0);
+  int result = recv (scb->fd, scb->buf, count, 0);
+  if (result == -1 && errno != EINTR)
+    perror_with_name ("error while reading");
+  return result;
 }
 
 static int
index a2a897d4442d8de1658c74d7691499702aac8ad6..07cd8b7b5b4bdbfccad8ff31fc86d5279f0d0ca1 100644 (file)
@@ -574,7 +574,10 @@ when debugging using remote targets."),
 int
 ser_unix_read_prim (struct serial *scb, size_t count)
 {
-  return read (scb->fd, scb->buf, count);
+  int result = recv (scb->fd, scb->buf, count, 0);
+  if (result == -1 && errno != EINTR)
+    perror_with_name ("error while reading");
+  return result;
 }
 
 int