From patchwork Thu Jan 28 00:48:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Breazeal X-Patchwork-Id: 10645 Received: (qmail 60964 invoked by alias); 28 Jan 2016 00:48:40 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 60936 invoked by uid 89); 28 Jan 2016 00:48:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=blah, Hx-languages-length:4057, *tp, UD:forking-threads-plus-breakpoint.exp X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 28 Jan 2016 00:48:37 +0000 Received: from svr-orw-fem-03.mgc.mentorg.com ([147.34.97.39]) by relay1.mentorg.com with esmtp id 1aOalG-00049B-Vm from Don_Breazeal@mentor.com for gdb-patches@sourceware.org; Wed, 27 Jan 2016 16:48:34 -0800 Received: from build4-lucid-cs (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.3.224.2; Wed, 27 Jan 2016 16:48:34 -0800 Received: by build4-lucid-cs (Postfix, from userid 1905) id 83EDB41303; Wed, 27 Jan 2016 16:48:34 -0800 (PST) From: Don Breazeal To: Subject: [PATCH 1/3] PR remote/19496, internal err forking-threads-plus-bkpt Date: Wed, 27 Jan 2016 16:48:29 -0800 Message-ID: <1453942111-1215-2-git-send-email-donb@codesourcery.com> In-Reply-To: <1453942111-1215-1-git-send-email-donb@codesourcery.com> References: <1453942111-1215-1-git-send-email-donb@codesourcery.com> MIME-Version: 1.0 X-IsSubscribed: yes This patch fixes an internal error that occurs in gdb.threads/forking-threads-plus-breakpoint.exp: /blah/binutils-gdb/gdb/target.c:2723: internal-error: Can't determine the current address space of thread Thread 3170.3170 In default_thread_address_space, find_inferior_ptid couldn't find 3170.3170 because it had been overwritten in inferior_appeared, called as follows: inferior_appeared remote_add_inferior remote_notice_new_inferior remote_update_thread_list The cause of the problem was the following sequence of events: * GDB knows only about the main thread * the first fork event is reported to GDB, saved as pending_event * qXfer:threads_read gets the threads from the remote. remove_new_fork_children id's the fork child from the pending event and removes it from the list reported to GDB. All the rest of the threads, including the fork parent, are added to the GDB thread list. * GDB stops all the threads. All the stop events are pushed onto the stop reply queue behind the pending fork event. * remote_wait_ns calls queued_stop_reply and process_stop_reply to remove the fork event from the front of the stop reply queue and save event information in the thread_info structure for the fork parent thread. Unfortunately, none of the information saved in this way is the fork-specific information, so the actual fork event info is lost. * A subsequent qXfer:threads:read packet gets the thread list including the fork parent and fork child. remove_new_fork_children checks the thread list to see if there is a fork parent, doesn't find one, checks the stop reply queue for a pending fork event, doesn't find one, and allows the fork child thread to be reported to GDB before the fork event has been handled. remote_update_thread_list calls remote_notice_new_thread and overwrites the current (main) thread in inferior_appeared. GDB has now lost all knowledge of the main thread, and an internal error results. The fix was to make sure that when the stop reply was removed from the stop reply queuei, all of the necessary fork event information was stored in the parent thread structure. In process_stop_reply we call a new function, update_thread_if_fork_parent, to store the pending_follow information from the fork stop reply in the fork parent thread. Tested on x86_64 and Nios II Linux. No regressions, but more failures, which are addressed in subsequent patches in this patchset. Thanks, --Don gdb/ChangeLog: 2016-01-27 Don Breazeal PR remote/19496 * remote.c (update_thread_if_fork_parent): New function. (process_stop_reply): Call update_thread_if_fork_parent. --- gdb/remote.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/gdb/remote.c b/gdb/remote.c index b0303f6..f072ce4 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -6799,6 +6799,25 @@ remote_notif_get_pending_events (struct notif_client *nc) } } +/* Check if the specified stop reply is for a fork event. If it is, + update the corresponding thread to contain the pending follow + information required to identify it as the fork parent. */ + +static void +update_thread_if_fork_parent (struct stop_reply *stop_reply) +{ + ptid_t ptid; + + ptid = stop_reply->ptid; + if (stop_reply->ws.kind == TARGET_WAITKIND_FORKED + || stop_reply->ws.kind == TARGET_WAITKIND_VFORKED) + { + struct thread_info *tp = find_thread_ptid (ptid); + + tp->pending_follow = stop_reply->ws; + } +} + /* Called when it is decided that STOP_REPLY holds the info of the event that is to be returned to the core. This function always destroys STOP_REPLY. */ @@ -6844,8 +6863,11 @@ process_stop_reply (struct stop_reply *stop_reply, remote_thr->core = stop_reply->core; remote_thr->stop_reason = stop_reply->stop_reason; remote_thr->watch_data_address = stop_reply->watch_data_address; - } + /* Make sure we record any pending fork events. */ + update_thread_if_fork_parent (stop_reply); + + } stop_reply_xfree (stop_reply); return ptid; }