From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 108810 invoked by alias); 6 May 2016 10:32:44 -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 108516 invoked by uid 89); 6 May 2016 10:32:42 -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=cancelled, 50227, dance 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, 06 May 2016 10:32:33 +0000 Received: by mail-pa0-f41.google.com with SMTP id bt5so46050358pac.3 for ; Fri, 06 May 2016 03:32:33 -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=wBN7QXoB1qW5yBlSDdT2oQFIVsDeXlmID7zW911cPF8=; b=F+l2pjQgHLNxVAbNLSasIy66S52mSiHax323nRoDbPpIWbBboy7PgA+PQQFyfty+Lt ssp5Bhm8vejs33OpRCTHcCrgiKPQtxApcFYbuVg+yn4Y2naYtjhQe8hIPA3xKcKW+x3l 0zAbdBTb6mTJdD8UYMDx+O31Lna4Uik6IstS3h8PWPDCYVPPrGEge3z6/gYcncW9ywMr WfOWTLwqVBWuQdchIdLKm90PJ4jb9IhZSUZrvIzIdhW5kdSZ6w9HKz0J0qp1F/MkNUPV coQGHlIDeZtryRCjLMrXaTeooRD0A395hv0tlqwhHyo0fn9wKYAqQCcajhAi7TiWMnam 4UGA== X-Gm-Message-State: AOPr4FX+CehNGixlvDat4A5HaE7j0aqF7/OpgQTVOOlKOri5exd8J6zlNmeUAClJk90Ejg== X-Received: by 10.66.43.143 with SMTP id w15mr27976441pal.76.1462530751558; Fri, 06 May 2016 03:32:31 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id qm10sm20041121pac.33.2016.05.06.03.32.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 May 2016 03:32:31 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [RFC 2/3] use reinsert breakpoint for vCont;s Date: Fri, 06 May 2016 10:32:00 -0000 Message-Id: <1462530736-25117-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1462530736-25117-1-git-send-email-yao.qi@linaro.org> References: <1462530736-25117-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes X-SW-Source: 2016-05/txt/msg00088.txt.bz2 This patch teaches GDBserver to handle vCont;s using software single step. That is, if the resume request is resume_step, insert reinsert breakpoint at the next pc address, and resume the thread. These reinsert breakpoints are removed in linux_wait_1, which I am not sure. gdb/gdbserver: 2016-04-26 Yao Qi * linux-low.c (linux_wait_1): Delete reinsert breakpoints in some cases. (linux_resume_one_thread): Call single_step if lwp->resume->kind is resume_step. (proceed_one_lwp): Call single_step. --- gdb/gdbserver/linux-low.c | 33 ++++++++++++++++++++++++++++++--- gdb/gdbserver/mem-break.c | 20 +++++++++++++++++++- gdb/gdbserver/mem-break.h | 7 ++++++- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index e539e34..2a9a1ad 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -3270,12 +3270,34 @@ linux_wait_1 (ptid_t ptid, if (debug_threads) debug_printf ("Hit a gdbserver breakpoint.\n"); } + + if (!step_over_finished && !can_hardware_single_step ()) + { + /* If the thread resumed by resume_step hits the reinsert + breakpoint, delete the reinsert breakpoint for it. */ + if (current_thread->last_resume_kind == resume_step) + delete_reinsert_breakpoints (current_thread); + else + { + /* If the thread resumed by other kind, like + resume_continue, hits the breakpoint (either + reinsert breakpoint or GDB breakpoint), delete + all reinsert breakpoints if it hits non-reinsert + breakpoints, otherwise, leave reinsert breakpoint there + and step over it. */ + if (non_reinsert_breakpoint_inserted_here (event_child->stop_pc)) + delete_reinsert_breakpoints (NULL); + } + } } else { /* We have some other signal, possibly a step-over dance was in progress, and it should be cancelled too. */ step_over_finished = finish_step_over (event_child); + + if (!step_over_finished && !can_hardware_single_step ()) + delete_reinsert_breakpoints (NULL); } /* We have all the data we need. Either report the event to GDB, or @@ -3568,6 +3590,8 @@ linux_wait_1 (ptid_t ptid, /* Alright, we're going to report a stop. */ + delete_reinsert_breakpoints (NULL); + if (!stabilizing_threads) { /* In all-stop, stop all threads. */ @@ -4765,7 +4789,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; @@ -4834,10 +4857,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 = single_step (lwp); + linux_resume_one_lwp (lwp, step, lwp->resume->sig, NULL); } else @@ -5022,7 +5049,7 @@ 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 = single_step (lwp); } else if (lwp->bp_reinsert != 0) { diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index 197d7a1..051325a 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -1431,7 +1431,8 @@ delete_reinsert_breakpoints (struct thread_info *thread) while (bp) { - if (bp->type == reinsert_breakpoint && bp->thread == thread) + if (bp->type == reinsert_breakpoint + && (bp->thread == thread || thread == NULL)) { *bp_link = bp->next; release_breakpoint (proc, bp); @@ -1692,6 +1693,23 @@ reinsert_breakpoint_inserted_here (CORE_ADDR addr) return 0; } +/* See mem-break.h. */ + +int +non_reinsert_breakpoint_inserted_here (CORE_ADDR addr) +{ + struct process_info *proc = current_process (); + struct breakpoint *bp; + + for (bp = proc->breakpoints; bp != NULL; bp = bp->next) + if (bp->type != reinsert_breakpoint + && bp->raw->pc == addr + && bp->raw->inserted) + return 1; + + return 0; +} + static int validate_inserted_breakpoint (struct raw_breakpoint *bp) { diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h index 2744584..e2aac80 100644 --- a/gdb/gdbserver/mem-break.h +++ b/gdb/gdbserver/mem-break.h @@ -104,6 +104,10 @@ int hardware_breakpoint_inserted_here (CORE_ADDR addr); int reinsert_breakpoint_inserted_here (CORE_ADDR addr); +/* Returns TRUE if there's any breakpoint other than reinsert at ADDR. */ + +int non_reinsert_breakpoint_inserted_here (CORE_ADDR addr); + /* Clear all breakpoint conditions and commands associated with a breakpoint. */ @@ -154,7 +158,8 @@ int delete_breakpoint (struct breakpoint *bkpt); void set_reinsert_breakpoint (CORE_ADDR stop_at, struct thread_info *thread); -/* Delete all reinsert breakpoints of THREAD. */ +/* Delete all reinsert breakpoints of THREAD. If THREAD is NULL, + delete all from all threads. */ void delete_reinsert_breakpoints (struct thread_info *thread); -- 1.9.1