diff options
author | Tom Tromey <tromey@adacore.com> | 2023-08-29 08:22:09 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2023-11-27 12:55:14 -0700 |
commit | 0da23004a064e7149373b484fa671f2a2105ec9b (patch) | |
tree | cd41c9b455ae17a9ab41b8b14a423efc94053204 | |
parent | d69939bded50d76179f97284df35879a385cf8c0 (diff) | |
download | gdb-0da23004a064e7149373b484fa671f2a2105ec9b.zip gdb-0da23004a064e7149373b484fa671f2a2105ec9b.tar.gz gdb-0da23004a064e7149373b484fa671f2a2105ec9b.tar.bz2 |
Change serial_readchar to throw
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
-rw-r--r-- | gdb/remote.c | 56 | ||||
-rw-r--r-- | gdb/ser-mingw.c | 12 | ||||
-rw-r--r-- | gdb/ser-tcp.c | 5 | ||||
-rw-r--r-- | gdb/ser-uds.c | 5 | ||||
-rw-r--r-- | gdb/ser-unix.c | 5 |
5 files changed, 41 insertions, 42 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index 49c1c96..22215b5 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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; } diff --git a/gdb/ser-mingw.c b/gdb/ser-mingw.c index 4607a10..25016ae 100644 --- a/gdb/ser-mingw.c +++ b/gdb/ser-mingw.c @@ -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; } diff --git a/gdb/ser-tcp.c b/gdb/ser-tcp.c index ce3c618..cfd1343 100644 --- a/gdb/ser-tcp.c +++ b/gdb/ser-tcp.c @@ -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 diff --git a/gdb/ser-uds.c b/gdb/ser-uds.c index baa660b..ad1f79e 100644 --- a/gdb/ser-uds.c +++ b/gdb/ser-uds.c @@ -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 diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c index a2a897d..07cd8b7 100644 --- a/gdb/ser-unix.c +++ b/gdb/ser-unix.c @@ -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 |