From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 83862 invoked by alias); 2 Jun 2016 09:31:17 -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 83626 invoked by uid 89); 2 Jun 2016 09:31:16 -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=arrives, Stop X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 02 Jun 2016 09:31:10 +0000 Received: by mail-pf0-f193.google.com with SMTP id 62so7351328pfd.3 for ; Thu, 02 Jun 2016 02:31:09 -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=aU5RPLKeRxGLvmSGfUOL+WE393YCN4nqmXfgNpTDNf8=; b=NZ99/xWFEkjThLiwUvU8YTe4fGEa36yE3RM38WT+C9hTN4m4LBH1/N0c9VgHJ9P+SM NEkeM0zVt2I6kdgnAYkUpagfVlqTEXzzBoINluwuThMEEt2HUuf6yPVb4dTi4J+aSNd5 xeVhxYSb684e2FTSktYbvGqmZg+A821DFTcEcc4fTmyuw8m1Slpt+z0wyyLHTRr+RL61 ftRGdN6UbsLkDYxLih3E3VO44zHs5+q6CCh1ygwm+yyuW7iMBBm8QUhFodX4LkPK7JrG gbWkozAFcPVKeCcYlhJVQO5a1e6bGgE23HqMpy/13CqsNqI6sWwyl7iD6ljCyT1epmXz n5Fg== X-Gm-Message-State: ALyK8tJgtLvzhOvSO/ryENMBPWqo/aLnF6XFq1qA4ufI9ecl7nnjUoJWLQA0tsb3ywRbgg== X-Received: by 10.98.8.69 with SMTP id c66mr2650482pfd.47.1464859868173; Thu, 02 Jun 2016 02:31:08 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc113.osuosl.org. [140.211.9.71]) by smtp.gmail.com with ESMTPSA id hw10sm68656218pac.15.2016.06.02.02.31.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 02 Jun 2016 02:31:07 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 11/12] Use reinsert_breakpoint for vCont;s Date: Thu, 02 Jun 2016 09:31:00 -0000 Message-Id: <1464859846-15619-12-git-send-email-yao.qi@linaro.org> In-Reply-To: <1464859846-15619-1-git-send-email-yao.qi@linaro.org> References: <1464859846-15619-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2016-06/txt/msg00027.txt.bz2 V2: fix spaces in changelog entry, use maybe_hw_step, cancel step-over if signal arrives (!maybe_internal_trap), This patch is to teach GDBserver using software single step to handle vCont;s. Simply speaking, if the thread's resume request is resume_step, install reinsert breakpoint at the next pcs when GDBserver is about to resume threads. These reinsert breakpoints of a thread are removed, when GDBserver gets an event from that thread. Note that GDBserver may or may not report this event back to GDB. gdb/gdbserver: 2016-05-20 Yao Qi * linux-low.c (resume_stopped_resumed_lwps): If resume request is resume_step, call maybe_hw_step. (linux_wait_1): Stop all threads, remove reinsert breakpoints, and unstop them. (linux_resume_one_thread): If resume request is resume_step, call maybe_hw_step. (linux_resume): Install reinsert breakpoints if the thread is requested to resume_step. (proceed_one_lwp): If resume request is resume_step, call maybe_hw_step. (proceed_all_lwps): Install reinsert breakpoints if the thread is requested to resume_step. --- gdb/gdbserver/linux-low.c | 99 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 6f32911..4e79ec1 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -2579,7 +2579,10 @@ resume_stopped_resumed_lwps (struct inferior_list_entry *entry) && !lp->status_pending_p && thread->last_status.kind == TARGET_WAITKIND_IGNORE) { - int step = thread->last_resume_kind == resume_step; + int step = 0; + + if (thread->last_resume_kind == resume_step) + step = maybe_hw_step (thread); if (debug_threads) debug_printf ("RSRL: resuming stopped-resumed LWP %s at %s: step=%d\n", @@ -3530,6 +3533,23 @@ linux_wait_1 (ptid_t ptid, return ignore_event (ourstatus); } + /* Remove reinsert breakpoints ... */ + if (can_software_single_step () + && has_reinsert_breakpoints (current_thread) + /*... if GDB requests this thread doing resume_step or ...*/ + && (current_thread->last_resume_kind == resume_step + /* GDBserver has already started the step-over for vCont;s, + but it gets some other signal, like SIGSTOP sent by + GDBserver for vCont;t or other signal program received. */ + || !maybe_internal_trap)) + { + stop_all_lwps (1, event_child); + + delete_reinsert_breakpoints (current_ptid); + + unstop_all_lwps (1, event_child); + } + /* Note that all addresses are always "out of the step range" when there's no range to begin with. */ in_step_range = lwp_in_step_range (event_child); @@ -4293,7 +4313,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, step = maybe_hw_step (thread); } - else + else if (lwp->resume != NULL && lwp->resume->kind != resume_step) { /* If the thread isn't doing step-over, there shouldn't be any reinsert breakpoints. */ @@ -4853,7 +4873,6 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) { struct thread_info *thread = (struct thread_info *) entry; struct lwp_info *lwp = get_thread_lwp (thread); - int step; int leave_all_stopped = * (int *) arg; int leave_pending; @@ -4922,10 +4941,14 @@ linux_resume_one_thread (struct inferior_list_entry *entry, void *arg) if (!leave_pending) { + int step = 0; + if (debug_threads) debug_printf ("resuming LWP %ld\n", lwpid_of (thread)); - step = (lwp->resume->kind == resume_step); + if (lwp->resume->kind == resume_step) + step = maybe_hw_step (thread); + linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL); } else @@ -4966,6 +4989,7 @@ linux_resume (struct thread_resume *resume_info, size_t n) struct thread_info *need_step_over = NULL; int any_pending; int leave_all_stopped; + int resume_step_is_handled = 0; if (debug_threads) { @@ -5009,12 +5033,52 @@ linux_resume (struct thread_resume *resume_info, size_t n) debug_printf ("Resuming, no pending status or step over needed\n"); } + /* Before we resume the threads, if resume_step is requested by GDB, + stop all threads and install reinsert breakpoints. */ + if (!leave_all_stopped && can_software_single_step ()) + { + struct inferior_list_entry *inf, *tmp; + + if (debug_threads) + debug_printf ("Handle resume_step.\n"); + + ALL_INFERIORS (&all_threads, inf, tmp) + { + struct thread_info *thread = (struct thread_info *) inf; + struct lwp_info *lwp = get_thread_lwp (thread); + + if (lwp->resume != NULL && lwp->resume->kind == resume_step) + { + if (!resume_step_is_handled) + { + stop_all_lwps (0, NULL); + + if (debug_threads) + debug_printf ("Done stopping all threads.\n"); + + resume_step_is_handled = 1; + } + + install_software_single_step_breakpoints (lwp); + + if (debug_threads) + debug_printf ("Insert breakpoint for resume_step LWP %ld\n", + lwpid_of (thread)); + } + } + + if (debug_threads) + debug_printf ("Handle resume_step. Done\n"); + } + /* Even if we're leaving threads stopped, queue all signals we'd otherwise deliver. */ find_inferior (&all_threads, linux_resume_one_thread, &leave_all_stopped); if (need_step_over) start_step_over (get_thread_lwp (need_step_over)); + else if (resume_step_is_handled) + unstop_all_lwps (0, NULL); if (debug_threads) { @@ -5110,7 +5174,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except) if (debug_threads) debug_printf (" stepping LWP %ld, client wants it stepping\n", lwpid_of (thread)); - step = 1; + + step = maybe_hw_step (thread); } else if (lwp->bp_reinsert != 0) { @@ -5176,6 +5241,30 @@ proceed_all_lwps (void) if (debug_threads) debug_printf ("Proceeding, no step-over needed\n"); + /* Re-install the reinsert breakpoints on software single step target + if the client wants it step. */ + if (can_software_single_step ()) + { + struct inferior_list_entry *inf, *tmp; + + ALL_INFERIORS (&all_threads, inf, tmp) + { + struct thread_info *thread = (struct thread_info *) inf; + + if (thread->last_resume_kind == resume_step) + { + struct lwp_info *lwp = get_thread_lwp (thread); + + if (!has_reinsert_breakpoints (thread)) + install_software_single_step_breakpoints (lwp); + + if (debug_threads) + debug_printf ("Insert breakpoint for resume_step LWP %ld\n", + lwpid_of (thread)); + } + } + } + find_inferior (&all_threads, proceed_one_lwp, NULL); } -- 1.9.1