From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5505 invoked by alias); 14 Oct 2015 15:37:10 -0000 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 Received: (qmail 5386 invoked by uid 89); 14 Oct 2015 15:37:09 -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,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 14 Oct 2015 15:37:03 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 5DFAA2F516F for ; Wed, 14 Oct 2015 15:28:15 +0000 (UTC) Received: from brno.lan (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9EFS6Dg016846 for ; Wed, 14 Oct 2015 11:28:14 -0400 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 07/18] gdbserver crash if gdb attaches too fast Date: Wed, 14 Oct 2015 15:37:00 -0000 Message-Id: <1444836486-25679-8-git-send-email-palves@redhat.com> In-Reply-To: <1444836486-25679-1-git-send-email-palves@redhat.com> References: <1444836486-25679-1-git-send-email-palves@redhat.com> X-SW-Source: 2015-10/txt/msg00228.txt.bz2 With "maint set target-non-stop on", the attach tests occasionally crash gdbserver. Basically, gdb attaches with vAttach;PID, and then shortly after reads the xml target description for that process, to figure out the process' architecture. On the gdbserver side, the target description is only filled in when the first process/thread in the thread group reports its initial PTRACE_ATTACH SIGSTOP. So if GDB is fast enough, it can read the target description _before_ that initial stop, and then gdbserver dies dereferencing a NULL tdesc pointer. gdb/gdbserver/ChangeLog: 2015-10-14 Pedro Alves * linux-low.c (linux_attach): In non-stop mode, wait for one stop before returning. --- gdb/gdbserver/linux-low.c | 53 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 3a1a6ae..90eafe2 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -1039,12 +1039,16 @@ attach_proc_task_lwp_callback (ptid_t ptid) return 0; } +static void async_file_mark (void); + /* Attach to PID. If PID is the tgid, attach to it and all of its threads. */ static int linux_attach (unsigned long pid) { + struct process_info *proc; + struct thread_info *initial_thread; ptid_t ptid = ptid_build (pid, pid, 0); int err; @@ -1055,17 +1059,12 @@ linux_attach (unsigned long pid) error ("Cannot attach to process %ld: %s", pid, linux_ptrace_attach_fail_reason_string (ptid, err)); - linux_add_process (pid, 1); - - if (!non_stop) - { - struct thread_info *thread; + proc = linux_add_process (pid, 1); - /* Don't ignore the initial SIGSTOP if we just attached to this - process. It will be collected by wait shortly. */ - thread = find_thread_ptid (ptid_build (pid, pid, 0)); - thread->last_resume_kind = resume_stop; - } + /* Don't ignore the initial SIGSTOP if we just attached to this + process. It will be collected by wait shortly. */ + initial_thread = find_thread_ptid (ptid_build (pid, pid, 0)); + initial_thread->last_resume_kind = resume_stop; /* We must attach to every LWP. If /proc is mounted, use that to find them now. On the one hand, the inferior may be using raw @@ -1077,6 +1076,38 @@ linux_attach (unsigned long pid) that once thread_db is loaded, we'll still use it to list threads and associate pthread info with each LWP. */ linux_proc_attach_tgid_threads (pid, attach_proc_task_lwp_callback); + + /* GDB will shortly read the xml target description for this + process, to figure out the process' architecture. But the target + description is only filled in when the first process/thread in + the thread group reports its initial PTRACE_ATTACH SIGSTOP. Do + that now, otherwise, if GDB is fast enough, it could read the + target description _before_ that initial stop. */ + if (non_stop) + { + struct lwp_info *lwp; + int wstat, lwpid; + ptid_t pid_ptid = pid_to_ptid (pid); + + lwpid = linux_wait_for_event_filtered (pid_ptid, pid_ptid, + &wstat, __WALL); + gdb_assert (lwpid > 0); + + lwp = find_lwp_pid (pid_to_ptid (lwpid)); + + if (!WIFSTOPPED (wstat) || WSTOPSIG (wstat) != SIGSTOP) + { + lwp->status_pending_p = 1; + lwp->status_pending = wstat; + } + + initial_thread->last_resume_kind = resume_continue; + + async_file_mark (); + + gdb_assert (proc->tdesc != NULL); + } + return 0; } @@ -2878,8 +2909,6 @@ linux_stabilize_threads (void) } } -static void async_file_mark (void); - /* Convenience function that is called when the kernel reports an event that is not passed out to GDB. */ -- 1.9.3