From patchwork Fri Feb 19 14:36:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 10924 Received: (qmail 104791 invoked by alias); 19 Feb 2016 14:36:45 -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 103777 invoked by uid 89); 19 Feb 2016 14:36:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=U*func, 201507, Normally, sk:connect X-HELO: mail-pa0-f41.google.com Received: from mail-pa0-f41.google.com (HELO mail-pa0-f41.google.com) (209.85.220.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 19 Feb 2016 14:36:42 +0000 Received: by mail-pa0-f41.google.com with SMTP id fy10so51278169pac.1 for ; Fri, 19 Feb 2016 06:36:42 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=G+XaU7E4o9GGbwz8fdZ3X7K0U08P0KrEa2gvvSd11JM=; b=haD/6O3+vhEJbyoZBye0wMNrdOfRQF/ZAM+B9Rcv0WXMaI20coY307/VLH+dcGsIbB UtZJTc9vEG8zLSvbPfDC4N02//GWqqDk42dDYXMHtV4FYuvuYB01dqVw8qG7m3HsePYB yAcJcRrY/fz2eqCy4wM6EN8WxJPDW6vvrknit5Gh7geraKZ6UHEm20XouIuW1a56bzvf bmVjt1E0ER6ZLccM8eNvDaoRB4GtOc82hhJO1rlbURm4YXRvT9RjRs4aCwytgruJC4zb 8l9prUyxhQhc8cc11pSiCY6IDqJUe2Z3bCl/IOb8fF2wYKRuK9P5hckvIAOA8PPjqlbW IF0Q== X-Gm-Message-State: AG10YOQVyML0P4BVwiSB6YTFJ2IJ/6xyn2GjiSxvvkoTHuJCELStkEm56U8guP8f6tECEg== X-Received: by 10.66.62.229 with SMTP id b5mr18844134pas.114.1455892600856; Fri, 19 Feb 2016 06:36:40 -0800 (PST) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id kq3sm18452546pab.24.2016.02.19.06.36.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 19 Feb 2016 06:36:40 -0800 (PST) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 1/8] [GDBserver] Leave child suspended when step over parent Date: Fri, 19 Feb 2016 14:36:27 +0000 Message-Id: <1455892594-2294-2-git-send-email-yao.qi@linaro.org> In-Reply-To: <1455892594-2294-1-git-send-email-yao.qi@linaro.org> References: <1455892594-2294-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes I see the following GDBserver internal error in two cases, gdb/gdbserver/linux-low.c:1922: A problem internal to GDBserver has been detected. unsuspend LWP 17200, suspended=-1 1. step over a breakpoint on fork/vfork syscall instruction, 2. step over a breakpoint on clone syscall instruction and child threads hits a breakpoint, the stack backtrace is #0 internal_error (file=file@entry=0x44c4c0 "gdb/gdbserver/linux-low.c", line=line@entry=1922, fmt=fmt@entry=0x44c7d0 "unsuspend LWP %ld, suspended=%d\n") at gdb/gdbserver/../common/errors.c:51 #1 0x0000000000424014 in lwp_suspended_decr (lwp=, lwp=) at gdb/gdbserver/linux-low.c:1922 #2 0x000000000042403a in unsuspend_one_lwp (entry=, except=0x66e8c0) at gdb/gdbserver/linux-low.c:2885 #3 0x0000000000405f45 in find_inferior (list=, func=func@entry=0x424020 , arg=arg@entry=0x66e8c0) at gdb/gdbserver/inferiors.c:243 #4 0x00000000004297de in unsuspend_all_lwps (except=0x66e8c0) at gdb/gdbserver/linux-low.c:2895 #5 linux_wait_1 (ptid=..., ourstatus=ourstatus@entry=0x665ec0 , target_options=target_options@entry=0) at gdb/gdbserver/linux-low.c:3632 #6 0x000000000042a764 in linux_wait (ptid=..., ourstatus=0x665ec0 , target_options=0) at gdb/gdbserver/linux-low.c:3770 #7 0x0000000000411163 in mywait (ptid=..., ourstatus=ourstatus@entry=0x665ec0 , options=options@entry=0, connected_wait=connected_wait@entry=1) at gdb/gdbserver/target.c:214 #8 0x000000000040b1f2 in resume (actions=0x66f800, num_actions=1) at gdb/gdbserver/server.c:2757 #9 0x000000000040f660 in handle_v_cont (own_buf=0x66a630 "vCont;c:p45e9.-1") at gdb/gdbserver/server.c:2719 when GDBserver steps over a thread, other threads have been suspended, the "stepping" thread may create new thread, but GDBserver doesn't set it suspend count to 1. When GDBserver unsuspend threads, the child's suspend count goes to -1, and the assert is triggered. In fact, GDBserver has already taken care of suspend count of new thread when GDBserver is suspending all threads except the one GDBserver wants to step over by https://sourceware.org/ml/gdb-patches/2015-07/msg00946.html + /* If we're suspending all threads, leave this one suspended + too. */ + if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS) + { + if (debug_threads) + debug_printf ("HEW: leaving child suspended\n"); + child_lwp->suspended = 1; + } but that is not enough, because new thread can be still spawned in the thread which is being stepped over. This patch extends the condition that GDBserver set child's suspend count to one if it is suspending threads or stepping over the thread. gdb/gdbserver: 2016-02-19 Yao Qi * linux-low.c (handle_extended_wait): Set child suspended if event_lwp->bp_reinsert isn't zero. --- gdb/gdbserver/linux-low.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 3f085fd..3765e08 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -529,8 +529,10 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) child_thr->last_status.kind = TARGET_WAITKIND_STOPPED; /* If we're suspending all threads, leave this one suspended - too. */ - if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS) + too. If we're stepping over the parent, all other threads + have been suspended already, leave this one suspended too. */ + if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS + || event_lwp->bp_reinsert != 0) { if (debug_threads) debug_printf ("HEW: leaving child suspended\n"); @@ -583,9 +585,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) before calling linux_resume_one_lwp. */ new_lwp->stopped = 1; - /* If we're suspending all threads, leave this one suspended - too. */ - if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS) + /* If we're suspending all threads, leave this one suspended + too. If we're stepping over the parent, all other threads + have been suspended already, leave this one suspended too. */ + if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS + || event_lwp->bp_reinsert != 0) new_lwp->suspended = 1; /* Normally we will get the pending SIGSTOP. But in some cases