From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 100833 invoked by alias); 14 Jun 2016 12:52:57 -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 100813 invoked by uid 89); 14 Jun 2016 12:52:56 -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=regcache, SRC X-HELO: mail-pa0-f65.google.com Received: from mail-pa0-f65.google.com (HELO mail-pa0-f65.google.com) (209.85.220.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 14 Jun 2016 12:52:46 +0000 Received: by mail-pa0-f65.google.com with SMTP id hf6so4846134pac.2 for ; Tue, 14 Jun 2016 05:52:46 -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:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=dGUEU0Pvbo8x+C9NtmRkuvcY1ellFZfj6uwcAOrhIIk=; b=KQZ7J8oTHwR+v82mZRAFk9F/GWdblfA08NjqSCa9HNorWc5blXeAzn9gHmZC6fnO6g bse1sc5N4mkGgzv3tSAoHXm59RuVFoUhxdeiDP+1hp3ReF5ER2zSP8ICbObsyDJ83EQ/ sqLii4AMmd2egonhGmVoRPi/l10AKumGQ4pPPVrL4pTXeB63kdgCc21z+8lRFiMo7qhl uGJ1x4yi82PW4UMNUYYbs1/winwjZW9PWZCkq/JZlNmNqktvA8KT48OOAGioMmamZhD6 Tj8EWyo1JrGwoOCbUFSu7SEwLpj7TalLjeEUWdvr5uZssUTDaFguMCPXaEjq1neU7UOS tLIQ== X-Gm-Message-State: ALyK8tKd8rzJKa7/zzZ6TtOrY0W9Q2z68Nw/b8/7fmxJkR71WM+o1JEgIPyAZZSdrSKF7g== X-Received: by 10.66.160.41 with SMTP id xh9mr17274604pab.85.1465908764513; Tue, 14 Jun 2016 05:52:44 -0700 (PDT) Received: from E107787-LIN (gcc113.osuosl.org. [140.211.9.71]) by smtp.gmail.com with ESMTPSA id h77sm13255822pfj.86.2016.06.14.05.52.39 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Tue, 14 Jun 2016 05:52:43 -0700 (PDT) From: Yao Qi To: Pedro Alves Cc: Yao Qi , gdb-patches@sourceware.org Subject: Re: [PATCH 09/12] Make reinsert_breakpoint thread specific References: <1464859846-15619-1-git-send-email-yao.qi@linaro.org> <1464859846-15619-10-git-send-email-yao.qi@linaro.org> <71a5322e-41e3-9e23-df73-e14b14c1d656@redhat.com> Date: Tue, 14 Jun 2016 12:52:00 -0000 In-Reply-To: <71a5322e-41e3-9e23-df73-e14b14c1d656@redhat.com> (Pedro Alves's message of "Mon, 13 Jun 2016 16:24:39 +0100") Message-ID: <86lh28szji.fsf@gmail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2016-06/txt/msg00251.txt.bz2 Pedro Alves writes: >> - uninsert_reinsert_breakpoints (); >> + uninsert_reinsert_breakpoints (ptid_of_lwp (event_lwp)); >> current_thread =3D saved_thread; > > Would it work to pass down the thread pointer directly? > > That would then allow pushing down the save current thread / restore > current thread juggling to uninsert_reinsert_breakpoints too. Yes, see the patch below, --=20 Yao (=E9=BD=90=E5=B0=A7) =46rom dd8c2dde049af0972d1da51506d990a97bf97193 Mon Sep 17 00:00:00 2001 From: Yao Qi Date: Thu, 19 May 2016 16:02:55 +0100 Subject: [PATCH] Make reinsert_breakpoint thread specific V3: pass argument "thread" isntead of "ptid" V2: rewrite commit log to make it easy to read, "id" -> "ptid", This patch makes reinsert_breakpoint thread specific, which means we insert and remove reinsert_breakpoint breakpoints for a specific thread. This motivation of this change is that I'll use reinsert_breakpoint for vCont;s on software single step target, so that GDBserver may insert one reinsert_breakpoint for one thread doing step-over, and insert one reinsert_breakpoint for another thread doing vCont;s. After the operation of one thread is finished, GDBserver must remove reinsert_breakpoint for that thread only. On the other hand, reinsert_breakpoint is used for step-over nowadays. GDBserver inserts reinsert_breakpoint, and wait only from the thread doing step-over. After the step-over is done, GDBserver removes the reinsert_breakpoint. If there is still any threads need step-over, do the same again until all threads are finished step-over. In other words, reinsert_breakpoint is globally thread specific, but in an implicit way. It is natural to make it explicitly thread specific. gdb/gdbserver: 2016-06-14 Yao Qi * mem-break.c (struct reinsert_breakpoint) : New field. (set_reinsert_breakpoint): New parameter ptid. Callers updated. (clone_one_breakpoint): Likewise. (delete_reinsert_breakpoints): Change parameter to thread. Callers updated. (has_reinsert_breakpoints): Likewise. (uninsert_reinsert_breakpoints): Likewise. (reinsert_reinsert_breakpoints): Likewise. * mem-break.h (set_reinsert_breakpoint): Update declaration. (delete_reinsert_breakpoints): Likewise. (reinsert_reinsert_breakpoints): Likewise. (uninsert_reinsert_breakpoints): Likewise. (has_reinsert_breakpoints): Likewise. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index b0af178..60759c8 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -548,15 +548,11 @@ handle_extended_wait (struct lwp_info **orig_event_lw= p, int wstat) && can_software_single_step () && event =3D=3D PTRACE_EVENT_VFORK) { - struct thread_info *saved_thread =3D current_thread; - - current_thread =3D event_thr; /* If we leave reinsert breakpoints there, child will hit it, so uninsert reinsert breakpoints from parent (and child). Once vfork child is done, reinsert them back to parent. */ - uninsert_reinsert_breakpoints (); - current_thread =3D saved_thread; + uninsert_reinsert_breakpoints (event_thr); } =20 clone_all_breakpoints (child_thr, event_thr); @@ -591,17 +587,13 @@ handle_extended_wait (struct lwp_info **orig_event_lw= p, int wstat) if (event_lwp->bp_reinsert !=3D 0 && can_software_single_step ()) { - struct thread_info *saved_thread =3D current_thread; - /* The child process is forked and stopped, so it is safe to access its memory without stopping all other threads from other processes. */ - current_thread =3D child_thr; - delete_reinsert_breakpoints (); - current_thread =3D saved_thread; + delete_reinsert_breakpoints (child_thr); =20 - gdb_assert (has_reinsert_breakpoints (parent_proc)); - gdb_assert (!has_reinsert_breakpoints (child_proc)); + gdb_assert (has_reinsert_breakpoints (event_thr)); + gdb_assert (!has_reinsert_breakpoints (child_thr)); } =20 /* Report the event. */ @@ -655,14 +647,9 @@ handle_extended_wait (struct lwp_info **orig_event_lwp= , int wstat) =20 if (event_lwp->bp_reinsert !=3D 0 && can_software_single_step ()) { - struct thread_info *saved_thread =3D current_thread; - struct process_info *proc =3D get_thread_process (event_thr); + reinsert_reinsert_breakpoints (event_thr); =20 - current_thread =3D event_thr; - reinsert_reinsert_breakpoints (); - current_thread =3D saved_thread; - - gdb_assert (has_reinsert_breakpoints (proc)); + gdb_assert (has_reinsert_breakpoints (event_thr)); } =20 /* Report the event. */ @@ -2559,11 +2546,9 @@ maybe_hw_step (struct thread_info *thread) return 1; else { - struct process_info *proc =3D get_thread_process (thread); - /* GDBserver must insert reinsert breakpoint for software single step. */ - gdb_assert (has_reinsert_breakpoints (proc)); + gdb_assert (has_reinsert_breakpoints (thread)); return 0; } } @@ -4153,7 +4138,7 @@ install_software_single_step_breakpoints (struct lwp_= info *lwp) next_pcs =3D (*the_low_target.get_next_pcs) (regcache); =20 for (i =3D 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); ++i) - set_reinsert_breakpoint (pc); + set_reinsert_breakpoint (pc, current_ptid); =20 do_cleanups (old_chain); } @@ -4296,7 +4281,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, { /* If the thread isn't doing step-over, there shouldn't be any reinsert breakpoints. */ - gdb_assert (!has_reinsert_breakpoints (proc)); + gdb_assert (!has_reinsert_breakpoints (thread)); } =20 if (fast_tp_collecting =3D=3D 1) @@ -4789,8 +4774,8 @@ finish_step_over (struct lwp_info *lwp) threads but LWP stopped while doing that. */ if (!can_hardware_single_step ()) { - gdb_assert (has_reinsert_breakpoints (current_process ())); - delete_reinsert_breakpoints (); + gdb_assert (has_reinsert_breakpoints (current_thread)); + delete_reinsert_breakpoints (current_thread); } =20 step_over_bkpt =3D null_ptid; diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index c14219e..65ca3f9 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -211,6 +211,9 @@ struct other_breakpoint struct reinsert_breakpoint { struct breakpoint base; + + /* Thread the reinsert breakpoint belongs to. */ + ptid_t ptid; }; =20 /* Return the breakpoint size from its kind. */ @@ -1476,17 +1479,21 @@ gdb_breakpoint_here (CORE_ADDR where) } =20 void -set_reinsert_breakpoint (CORE_ADDR stop_at) +set_reinsert_breakpoint (CORE_ADDR stop_at, ptid_t ptid) { - struct breakpoint *bp; + struct reinsert_breakpoint *bp; + + gdb_assert (ptid_get_pid (current_ptid) =3D=3D ptid_get_pid (ptid)); =20 - bp =3D set_breakpoint_type_at (reinsert_breakpoint, stop_at, NULL); + bp =3D (struct reinsert_breakpoint *) set_breakpoint_type_at (reinsert_b= reakpoint, + stop_at, NULL); + bp->ptid =3D ptid; } =20 void -delete_reinsert_breakpoints (void) +delete_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc =3D current_process (); + struct process_info *proc =3D get_thread_process (thread); struct breakpoint *bp, **bp_link; =20 bp =3D proc->breakpoints; @@ -1494,11 +1501,17 @@ delete_reinsert_breakpoints (void) =20 while (bp) { - if (bp->type =3D=3D reinsert_breakpoint) + if (bp->type =3D=3D reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { + struct thread_info *saved_thread =3D current_thread; + + current_thread =3D thread; *bp_link =3D bp->next; release_breakpoint (proc, bp); bp =3D *bp_link; + current_thread =3D saved_thread; } else { @@ -1578,21 +1591,29 @@ uninsert_all_breakpoints (void) } =20 void -uninsert_reinsert_breakpoints (void) +uninsert_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc =3D current_process (); + struct process_info *proc =3D get_thread_process (thread); struct breakpoint *bp; =20 for (bp =3D proc->breakpoints; bp !=3D NULL; bp =3D bp->next) { - if (bp->type =3D=3D reinsert_breakpoint) + if (bp->type =3D=3D reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { gdb_assert (bp->raw->inserted > 0); =20 /* Only uninsert the raw breakpoint if it only belongs to a reinsert breakpoint. */ if (bp->raw->refcount =3D=3D 1) - uninsert_raw_breakpoint (bp->raw); + { + struct thread_info *saved_thread =3D current_thread; + + current_thread =3D thread; + uninsert_raw_breakpoint (bp->raw); + current_thread =3D saved_thread; + } } } } @@ -1642,8 +1663,9 @@ reinsert_breakpoints_at (CORE_ADDR pc) } =20 int -has_reinsert_breakpoints (struct process_info *proc) +has_reinsert_breakpoints (struct thread_info *thread) { + struct process_info *proc =3D get_thread_process (thread); struct breakpoint *bp, **bp_link; =20 bp =3D proc->breakpoints; @@ -1651,7 +1673,9 @@ has_reinsert_breakpoints (struct process_info *proc) =20 while (bp) { - if (bp->type =3D=3D reinsert_breakpoint) + if (bp->type =3D=3D reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) return 1; else { @@ -1677,19 +1701,27 @@ reinsert_all_breakpoints (void) } =20 void -reinsert_reinsert_breakpoints (void) +reinsert_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc =3D current_process (); + struct process_info *proc =3D get_thread_process (thread); struct breakpoint *bp; =20 for (bp =3D proc->breakpoints; bp !=3D NULL; bp =3D bp->next) { - if (bp->type =3D=3D reinsert_breakpoint) + if (bp->type =3D=3D reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { gdb_assert (bp->raw->inserted > 0); =20 if (bp->raw->refcount =3D=3D 1) - reinsert_raw_breakpoint (bp->raw); + { + struct thread_info *saved_thread =3D current_thread; + + current_thread =3D thread; + reinsert_raw_breakpoint (bp->raw); + current_thread =3D saved_thread; + } } } } @@ -2113,7 +2145,7 @@ clone_agent_expr (const struct agent_expr *src_ax) /* Deep-copy the contents of one breakpoint to another. */ =20 static struct breakpoint * -clone_one_breakpoint (const struct breakpoint *src) +clone_one_breakpoint (const struct breakpoint *src, ptid_t ptid) { struct breakpoint *dest; struct raw_breakpoint *dest_raw; @@ -2174,6 +2206,9 @@ clone_one_breakpoint (const struct breakpoint *src) =3D XCNEW (struct reinsert_breakpoint); =20 dest =3D (struct breakpoint *) reinsert_dest; + /* Since reinsert breakpoint is thread specific, don't copy + thread id from SRC, use ID instead. */ + reinsert_dest->ptid =3D ptid; } else gdb_assert_not_reached ("unhandled breakpoint type"); @@ -2201,7 +2236,7 @@ clone_all_breakpoints (struct thread_info *child_thre= ad, =20 for (bp =3D parent_proc->breakpoints; bp !=3D NULL; bp =3D bp->next) { - new_bkpt =3D clone_one_breakpoint (bp); + new_bkpt =3D clone_one_breakpoint (bp, ptid_of (child_thread)); APPEND_TO_LIST (new_list, new_bkpt, bkpt_tail); APPEND_TO_LIST (new_raw_list, new_bkpt->raw, raw_bkpt_tail); } diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h index d633003..3322ec5 100644 --- a/gdb/gdbserver/mem-break.h +++ b/gdb/gdbserver/mem-break.h @@ -152,31 +152,32 @@ struct breakpoint *set_breakpoint_at (CORE_ADDR where, =20 int delete_breakpoint (struct breakpoint *bkpt); =20 -/* Set a reinsert breakpoint at STOP_AT. */ +/* Set a reinsert breakpoint at STOP_AT for thread represented by + PTID. */ =20 -void set_reinsert_breakpoint (CORE_ADDR stop_at); +void set_reinsert_breakpoint (CORE_ADDR stop_at, ptid_t ptid); =20 -/* Delete all reinsert breakpoints. */ +/* Delete all reinsert breakpoints of THREAD. */ =20 -void delete_reinsert_breakpoints (void); +void delete_reinsert_breakpoints (struct thread_info *thread); =20 -/* Reinsert all reinsert breakpoints of the current process. */ +/* Reinsert all reinsert breakpoints of THREAD. */ =20 -void reinsert_reinsert_breakpoints (void); +void reinsert_reinsert_breakpoints (struct thread_info *thread); =20 -/* Uninsert all reinsert breakpoints of the current process. This - still leaves the reinsert breakpoints in the table. */ +/* Uninsert all reinsert breakpoints of THREAD. This still leaves + the reinsert breakpoints in the table. */ =20 -void uninsert_reinsert_breakpoints (void); +void uninsert_reinsert_breakpoints (struct thread_info *thread); =20 /* Reinsert breakpoints at WHERE (and change their status to inserted). */ =20 void reinsert_breakpoints_at (CORE_ADDR where); =20 -/* Process PROC has reinsert breakpoints or not. */ +/* The THREAD has reinsert breakpoints or not. */ =20 -int has_reinsert_breakpoints (struct process_info *proc); +int has_reinsert_breakpoints (struct thread_info *thread); =20 /* Uninsert breakpoints at WHERE (and change their status to uninserted). This still leaves the breakpoints in the table. */