2013-04-22 Pedro Alves Maciej W. Rozycki gdb/ * remote.c (remote_kill): Handle errors from the kill packet gracefully. Index: gdb/remote.c =================================================================== --- gdb.orig/remote.c 2013-04-22 14:13:25.512124202 +0200 +++ gdb/remote.c 2013-04-22 14:13:39.744123949 +0200 @@ -7714,12 +7714,36 @@ putpkt_for_catch_errors (void *arg) static void remote_kill (struct target_ops *ops) { - /* Use catch_errors so the user can quit from gdb even when we + struct gdb_exception ex; + + /* 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); + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + putpkt ("k"); + } + if (ex.reason < 0) + { + if (remote_desc == NULL) + { + /* 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); + } - /* 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. */ + /* 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 (); }