From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28198 invoked by alias); 8 Jul 2008 20:05:22 -0000 Received: (qmail 28189 invoked by uid 22791); 8 Jul 2008 20:05:21 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 08 Jul 2008 20:05:04 +0000 Received: (qmail 839 invoked from network); 8 Jul 2008 20:05:02 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 8 Jul 2008 20:05:02 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: Re: [RFA] thread specific breakpoints and single stepping Date: Tue, 08 Jul 2008 20:05:00 -0000 User-Agent: KMail/1.9.9 Cc: Ems SUZUKI References: <20080708.114916.68479315.emi-suzuki@tjsys.co.jp> In-Reply-To: <20080708.114916.68479315.emi-suzuki@tjsys.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200807082105.02583.pedro@codesourcery.com> X-IsSubscribed: yes 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 X-SW-Source: 2008-07/txt/msg00118.txt.bz2 A Tuesday 08 July 2008 03:49:16, Ems SUZUKI wrote: > > After the program reached to line 9, I set a breakpoint for only > thread 1 at line 10. =C2=A0And I invoked step for thread 2. =C2=A0I expec= ted > thread 2 would stop at line 10, but it hopped over there and stopped > at line 11. =C2=A0(I've attached the program I used to this mail.) > > The cause is in the below: > > infrun.c:2117 > > =C2=A0 =C2=A0 =C2=A0 if (regular_breakpoint_inserted_here_p (stop_pc)) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ecs->random_signal =3D 0; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!breakpoint_thread_match (stop_pc,= ecs->ptid)) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 thread_hop_needed =3D 1; > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > > thread_hop_needed would be set as 1, in the case that the stopped > thread does not match the condition of the breakpoint. =C2=A0The thread > which is currently single-stepping would also go into here. =C2=A0But the > stepping thread should not hop over the breakpoints unconditionally, > but check if it has reached the location where stepping would end. =C2=A0 > > I think I've add a check for it with the attached diff. =C2=A0Does it make > sense? > Index: gdb/infrun.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > RCS file: /cvs/src/src/gdb/infrun.c,v > retrieving revision 1.284 > diff -u -r1.284 infrun.c > --- gdb/infrun.c 28 Jun 2008 09:42:15 -0000 1.284 > +++ gdb/infrun.c 8 Jul 2008 02:34:39 -0000 > @@ -2118,7 +2118,11 @@ > { > ecs->random_signal =3D 0; > if (!breakpoint_thread_match (stop_pc, ecs->ptid)) > - thread_hop_needed =3D 1; > + /* If the thread is currently single-stepping, whether it will > + step over the breakpoint or not should be determined later. > */ + if (!ptid_equal (ecs->ptid, inferior_ptid) > + || !currently_stepping (ecs)) > + thread_hop_needed =3D 1; > } > else if (singlestep_breakpoints_inserted_p) > { I don't think that's correct. You can't be sure inferior_ptid is the user stepping thread at this point. GDB may have context-switched already due to another event having happened in another thread after the user started the step, and before reaching here. E.g., it could have been that another thread had already thread-hoped this breakpoint, see a bit below: if (thread_hop_needed) { ... else { /* Single step */ if (!ptid_equal (inferior_ptid, ecs->ptid)) context_switch (ecs); ecs->waiton_ptid =3D ecs->ptid; ecs->wp =3D &(ecs->ws); ecs->stepping_over_breakpoint =3D 1; ecs->infwait_state =3D infwait_thread_hop_state; keep_going (ecs); registers_changed (); return; } } Also, currently_stepping will return true for cases other than single-stepping due to user request. I think that what you want is: if (regular_breakpoint_inserted_here_p (stop_pc)) { ecs->random_signal =3D 0; if (!breakpoint_thread_match (stop_pc, ecs->ptid)) { if (!ptid_equal (inferior_ptid, ecs->ptid)) context_switch (ecs); /* If the thread is currently single-stepping, whether it will step over the this breakpoint or not should be determined later. */ if (!(step_range_end && step_resume_breakpoint =3D=3D NULL)) thread_hop_needed =3D 1; } } bpstat_stop_status will then find that this PC is not to be stopped (wrong thread), and the single-stepping will continue, if still within range (just like you suggested). Does it work for you? Could you convert your testcase into a test for GDB's testsuite? Also could you provide a ChangeLog entry along with the patch? Thanks! --=20 Pedro Alves