diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e7998b9aa6..3d8ed206ff 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2013-12-02 Pedro Alves + Maciej W. Rozycki + + * remote.c (putpkt_for_catch_errors): Remove function. + (remote_kill): Handle TARGET_CLOSE_ERROR from the kill packet + gracefully. + 2013-12-02 Pedro Alves PR remote/15974 diff --git a/gdb/remote.c b/gdb/remote.c index aa41264b60..2ac8c36725 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -7816,23 +7816,39 @@ getpkt_or_notif_sane (char **buf, long *sizeof_buf, int forever, } -/* A helper function that just calls putpkt; for type correctness. */ - -static int -putpkt_for_catch_errors (void *arg) -{ - return putpkt (arg); -} - static void remote_kill (struct target_ops *ops) { - /* Use catch_errors so the user can quit from gdb even when we - aren't on speaking terms with the remote system. */ - catch_errors (putpkt_for_catch_errors, "k", "", RETURN_MASK_ERROR); + struct gdb_exception ex; - /* Don't wait for it to die. I'm not really sure it matters whether - we do or not. For the existing stubs, kill is a noop. */ + /* Catch errors so the user can quit from gdb even when we + aren't on speaking terms with the remote system. */ + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + putpkt ("k"); + } + if (ex.reason < 0) + { + if (ex.error == TARGET_CLOSE_ERROR) + { + /* If we got an (EOF) error that caused the target + to go away, then we're done, that's what we wanted. + "k" is susceptible to cause a premature EOF, given + that the remote server isn't actually required to + reply to "k", and it can happen that it doesn't + even get to reply ACK to the "k". */ + return; + } + + /* Otherwise, something went wrong. We didn't actually kill + the target. Just propagate the exception, and let the + user or higher layers decide what to do. */ + throw_exception (ex); + } + + /* We've killed the remote end, we get to mourn it. Since this is + target remote, single-process, mourning the inferior also + unpushes remote_ops. */ target_mourn_inferior (); }