From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2729 invoked by alias); 12 Dec 2008 01:11:43 -0000 Received: (qmail 2718 invoked by uid 22791); 12 Dec 2008 01:11:42 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 12 Dec 2008 01:11:06 +0000 Received: (qmail 5057 invoked from network); 12 Dec 2008 01:11:04 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 12 Dec 2008 01:11:04 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: remote, defer deleting the inferior until it is mourned Date: Fri, 12 Dec 2008 01:11:00 -0000 User-Agent: KMail/1.9.10 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_xobQJ8K0AiPu4W8" Message-Id: <200812120111.13658.pedro@codesourcery.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-12/txt/msg00222.txt.bz2 --Boundary-00=_xobQJ8K0AiPu4W8 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1837 If we delete an inferior with delete_inferior (which tries to deletes all of its child threads) while one of its threads is selected, delete_thread will refuse to unlist it, but will instead tag it as exited. When we get to do a generic_mourn_inferior, we will no longer find the inferior listed, so this exited thread was left behind, but we do set inferior_ptid to null_ptid. This happens to then trigger an internal error in mi-main.c:mi_execute_command: ... if (/* The notifications are only output when the top-level interpreter (specified on the command line) is MI. */ ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())) /* Don't try report anything if there are no threads -- the program is dead. */ && thread_count () != 0 /* -thread-select explicitly changes thread. If frontend uses that internally, we don't want to emit =thread-selected, since =thread-selected is supposed to indicate user's intentions. */ && strcmp (command->command, "thread-select") != 0) { struct mi_interp *mi = top_level_interpreter_data (); struct thread_info *ti = inferior_thread (); ^^^^^^^^^^^^^^^^^^ ... here, since inferior_ptid was pointing at null_ptid, and, thread_count() returned 1. null_ptid is never a listed thread, so inferior_thread rightfully asserts. To fix this, we either set inferior_ptid to null_ptid before deleting the inferior when we want to prevent this, or, we defer deleting the inferior to generic_mourn_inferior, which does just that. I've done the latter. This also goes in the direction of what we were talking about in the infrun cleanup thread, about the inferior being already gone when we handle an inferior exit event. Tested against an x86_64-linux-gnu gdbserver. Checked in. -- Pedro Alves --Boundary-00=_xobQJ8K0AiPu4W8 Content-Type: text/x-diff; charset="iso 8859-15"; name="remote_mourn.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="remote_mourn.diff" Content-length: 2368 2008-12-12 Pedro Alves * remote.c (remote_detach_1): Don't delete the inferior here. (process_stop_reply): Ditto. (extended_remote_kill): Ditto. --- gdb/remote.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) Index: src/gdb/remote.c =================================================================== --- src.orig/gdb/remote.c 2008-12-12 00:48:29.000000000 +0000 +++ src/gdb/remote.c 2008-12-12 00:48:37.000000000 +0000 @@ -3316,7 +3316,6 @@ remote_detach_1 (char *args, int from_tt } discard_pending_stop_replies (pid); - detach_inferior (pid); target_mourn_inferior (); } @@ -4510,31 +4509,28 @@ process_stop_reply (struct stop_reply *s if (ptid_equal (ptid, null_ptid)) ptid = inferior_ptid; - if (status->kind == TARGET_WAITKIND_EXITED - || status->kind == TARGET_WAITKIND_SIGNALLED) + if (status->kind != TARGET_WAITKIND_EXITED + && status->kind != TARGET_WAITKIND_SIGNALLED) { - int pid = ptid_get_pid (ptid); - delete_inferior (pid); - } - else - notice_new_inferiors (ptid); + notice_new_inferiors (ptid); - /* Expedited registers. */ - if (stop_reply->regcache) - { - cached_reg_t *reg; - int ix; + /* Expedited registers. */ + if (stop_reply->regcache) + { + cached_reg_t *reg; + int ix; - for (ix = 0; - VEC_iterate(cached_reg_t, stop_reply->regcache, ix, reg); - ix++) - regcache_raw_supply (get_thread_regcache (ptid), - reg->num, reg->data); - VEC_free (cached_reg_t, stop_reply->regcache); - } + for (ix = 0; + VEC_iterate(cached_reg_t, stop_reply->regcache, ix, reg); + ix++) + regcache_raw_supply (get_thread_regcache (ptid), + reg->num, reg->data); + VEC_free (cached_reg_t, stop_reply->regcache); + } - remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p; - remote_watch_data_address = stop_reply->watch_data_address; + remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p; + remote_watch_data_address = stop_reply->watch_data_address; + } stop_reply_xfree (stop_reply); return ptid; @@ -6509,7 +6505,6 @@ extended_remote_kill (void) if (res != 0) error (_("Can't kill process")); - delete_inferior (pid); target_mourn_inferior (); } --Boundary-00=_xobQJ8K0AiPu4W8--