From patchwork Fri May 20 15:12:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 12415 Received: (qmail 68045 invoked by alias); 20 May 2016 15:13:07 -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 67870 invoked by uid 89); 20 May 2016 15:13:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=hitting, UD:id, 4714 X-HELO: mail-pa0-f67.google.com Received: from mail-pa0-f67.google.com (HELO mail-pa0-f67.google.com) (209.85.220.67) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 20 May 2016 15:12:54 +0000 Received: by mail-pa0-f67.google.com with SMTP id xm6so11172698pab.3 for ; Fri, 20 May 2016 08:12:54 -0700 (PDT) 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=6GiugGhmYB9pWRoqxRKLSCjH4euf/bptmZ8vWwGoIeo=; b=EDmu7th/AnqFzJCqCMV0+wgxXcmROwDsf+glnRrVkr034BH+BPyTB38LEQp/I5ngfI KIzJ4oVfxemMbV5Ssi4P/e+lFFSld4m7xknzm1dvsuHp3Bayk/Qefq+DMexPreIeQGXr 24geryIU8ef06uk4DOJl0ZTINIrY+bEM/dtY8x2e2+F5ZCBwbcGs3vMw6YozfU4xgNIK bJAjgz3qQDDlkT9CaX52GIwVHxMa4RnD1Rn5GzIv+3kUC95xm03d0qdszP8LsmzlkYWz +5laJ2/PHFCC8JPbQVSppN8Y9xjoeOw7ZMFKKkOC7zB8fmE4vUrybLnwxEt4Vdo3OtzH xy+g== X-Gm-Message-State: AOPr4FX7xFW7VOgDs8hom9fpXOqG7aOWShTBGhnX2FTLEEqoi5gSOaj5IaRTGMAMzkxSug== X-Received: by 10.66.189.135 with SMTP id gi7mr5544101pac.158.1463757172503; Fri, 20 May 2016 08:12:52 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc113.osuosl.org. [140.211.9.71]) by smtp.gmail.com with ESMTPSA id p80sm27985272pfj.58.2016.05.20.08.12.51 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 20 May 2016 08:12:51 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 1/8] Switch to current thread before finish_step_over Date: Fri, 20 May 2016 16:12:34 +0100 Message-Id: <1463757161-25850-2-git-send-email-yao.qi@linaro.org> In-Reply-To: <1463757161-25850-1-git-send-email-yao.qi@linaro.org> References: <1463757161-25850-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes This patch adds some sanity check that reinsert breakpoints must be there when doing step-over on software single step target. The check triggers an assert when running forking-threads-plus-breakpoint.exp on arm-linux target, gdb/gdbserver/linux-low.c:4714: A problem internal to GDBserver has been detected.^M int finish_step_over(lwp_info*): Assertion `has_reinsert_breakpoints ()' failed. the error happens when GDBserver has already resumed a thread of process A for step-over (and wait for it hitting reinsert breakpoint), but receives detach request for process B from GDB, which is shown in the backtrace below, (gdb) bt #2 0x000228aa in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4703 #3 0x00025a50 in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4749 #4 complete_ongoing_step_over () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4760 #5 linux_detach (pid=25228) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1503 #6 0x00012bae in process_serial_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3974 #7 handle_serial_event (err=, client_data=) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:4347 #8 0x00016d68 in handle_file_event (event_file_desc=) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:429 #9 0x000173ea in process_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:184 #10 start_event_loop () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:547 #11 0x0000aa2c in captured_main (argv=, argc=) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3719 #12 main (argc=, argv=) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3804 the sanity check tries to find the reinsert breakpoint from process B, but nothing is found. It is wrong, we need to search in process A, since we started step-over of a thread of process A. (gdb) p lwp->thread->entry.id $3 = {pid = 25120, lwp = 25131, tid = 0} (gdb) p current_thread->entry.id $4 = {pid = 25228, lwp = 25228, tid = 0} This patch switched current_thread to the step we are doing step-over in complete_ongoing_step_over. gdb/gdbserver: 2016-05-19 Yao Qi * linux-low.c (linux_resume_one_lwp_throw): Call has_reinsert_breakpoints. (finish_step_over): Likewise. (proceed_one_lwp): Likewise. * mem-break.c (has_reinsert_breakpoints): New function. * mem-break.h (has_reinsert_breakpoints): Declare. --- gdb/gdbserver/linux-low.c | 30 +++++++++++++++++++++++++----- gdb/gdbserver/mem-break.c | 22 ++++++++++++++++++++++ gdb/gdbserver/mem-break.h | 4 ++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 81134b0..8e8f710 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -4218,6 +4218,11 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, step = 1; } + else + { + gdb_assert (step == 0); + gdb_assert (has_reinsert_breakpoints (proc)); + } } if (fast_tp_collecting == 1) @@ -4705,7 +4710,10 @@ finish_step_over (struct lwp_info *lwp) because we were stepping over a breakpoint, and we hold all threads but LWP stopped while doing that. */ if (!can_hardware_single_step ()) - delete_reinsert_breakpoints (); + { + gdb_assert (has_reinsert_breakpoints (current_process ())); + delete_reinsert_breakpoints (); + } step_over_bkpt = null_ptid; return 1; @@ -4741,7 +4749,13 @@ complete_ongoing_step_over (void) lwp = find_lwp_pid (step_over_bkpt); if (lwp != NULL) - finish_step_over (lwp); + { + struct thread_info *saved_thread = current_thread; + + current_thread = get_lwp_thread (lwp); + finish_step_over (lwp); + current_thread = saved_thread; + } step_over_bkpt = null_ptid; unsuspend_all_lwps (lwp); } @@ -5017,6 +5031,7 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) send_sigstop (lwp); } + step = 0; if (thread->last_resume_kind == resume_step) { if (debug_threads) @@ -5029,10 +5044,15 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) if (debug_threads) debug_printf (" stepping LWP %ld, reinsert set\n", lwpid_of (thread)); - step = 1; + + if (can_hardware_single_step ()) + step = 1; + else + { + /* GDBserver must insert reinsert breakpoint for step-over. */ + gdb_assert (has_reinsert_breakpoints (get_thread_process (thread))); + } } - else - step = 0; linux_resume_one_lwp (lwp, step, 0, NULL); return 0; diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index 363d7ca..3313459 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -1553,6 +1553,28 @@ reinsert_breakpoints_at (CORE_ADDR pc) } } +int +has_reinsert_breakpoints (struct process_info *proc) +{ + struct breakpoint *bp, **bp_link; + + bp = proc->breakpoints; + bp_link = &proc->breakpoints; + + while (bp) + { + if (bp->type == reinsert_breakpoint) + return 1; + else + { + bp_link = &bp->next; + bp = *bp_link; + } + } + + return 0; +} + void reinsert_all_breakpoints (void) { diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h index 4d9a76c..b84dc1e 100644 --- a/gdb/gdbserver/mem-break.h +++ b/gdb/gdbserver/mem-break.h @@ -163,6 +163,10 @@ void delete_reinsert_breakpoints (void); void reinsert_breakpoints_at (CORE_ADDR where); +/* Process PROC has reinsert breakpoints or not. */ + +int has_reinsert_breakpoints (struct process_info *proc); + /* Uninsert breakpoints at WHERE (and change their status to uninserted). This still leaves the breakpoints in the table. */