From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9960 invoked by alias); 6 Jun 2014 11:12:54 -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 9950 invoked by uid 89); 6 Jun 2014 11:12:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Jun 2014 11:12:52 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s56BCoGR012667 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 6 Jun 2014 07:12:50 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s56BClQN017091; Fri, 6 Jun 2014 07:12:48 -0400 Message-ID: <5391A22E.1010600@redhat.com> Date: Fri, 06 Jun 2014 11:12:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: "Breazeal, Don" , gdb-patches@sourceware.org Subject: Re: [PATCH] Fix for follow-fork: followed child doesn't stop References: <1401920383-10219-1-git-send-email-donb@codesourcery.com> <53906804.3070107@redhat.com> <5390B82C.6010807@codesourcery.com> In-Reply-To: <5390B82C.6010807@codesourcery.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-SW-Source: 2014-06/txt/msg00313.txt.bz2 On 06/05/2014 07:34 PM, Breazeal, Don wrote: > Hi Pedro, > Thanks for looking at this. > > On 6/5/2014 5:52 AM, Pedro Alves wrote: >> Hi Don, >> >> On 06/04/2014 11:19 PM, Don Breazeal wrote: >>> Using the test program gdb.base/foll-fork.c, with follow-fork-mode >>> set to "child" and detach-on-fork set to "on", stepping past the >>> fork call results in the child process running to completion, when >>> it should just finish the single step. >>> >>> This is the result of how the single-step state is transferred from >>> the parent to the child in infrun.c:follow_fork. For the parent, the >>> single-step breakpoint is marked as "inserted" (bp->loc->inserted). >> >>> The breakpoint is transferred to the child, where it clearly has never >>> been inserted. >> >> Was it removed from the parent already at this point? If so, >> why is it still marked as inserted? If not, then it would sound >> like your patch would make us miss removing it. >> > Yes, by the time the 'inserted' flag is cleared, the breakpoint has been > removed from the parent. The flag is set because the child's breakpoint > is a clone of the parent's breakpoint that was created before the > parent's breakpoint was removed. It actually hasn't. > > The step-resume breakpoint is cloned from the parent's copy earlier in > the function, bringing the value of the 'inserted' flag along with it. > Then the parent's breakpoint is deleted, with the side-effect of > removing it. No, when the parent's breakpoint is deleted, nothing is removed, because the child's breakpoint, being a clone of the parent's is still associated with the parent thread and pspace, so the breakpoints module considers it a duplicate of the parent's sr breakpoint. So, when we delete the parent breakpoint, given the child's is around, we don't actually remove the breakpoint from the target. We just happen to remove the new _child_'s breakpoint from the parent a bit later when we detach the parent, again because the child's is still associated with the parent: (top-gdb) bt #0 target_remove_breakpoint (gdbarch=0x1000ee0, bp_tgt=0x10db7d8) at ../../src/gdb/target.c:1938 #1 0x0000000000584aac in bkpt_remove_location (bl=0x10db740) at ../../src/gdb/breakpoint.c:13189 #2 0x0000000000574095 in remove_breakpoint_1 (bl=0x10db740, is=mark_uninserted) at ../../src/gdb/breakpoint.c:3823 #3 0x0000000000574436 in remove_breakpoint (bl=0x10db740, is=mark_uninserted) at ../../src/gdb/breakpoint.c:3940 #4 0x0000000000572d41 in remove_breakpoints_pid (pid=1408) at ../../src/gdb/breakpoint.c:3119 #5 0x000000000063d5f8 in target_detach (args=0x0, from_tty=0) at ../../src/gdb/target.c:2079 #6 0x00000000004b1c81 in linux_child_follow_fork (ops=0xdcfc30, follow_child=1, detach_fork=1) at ../../src/gdb/linux-nat.c:657 #7 0x00000000006372b6 in delegate_follow_fork (self=0xdcfc30, arg1=1, arg2=1) at ../../src/gdb/target-delegates.c:464 #8 0x000000000063daed in target_follow_fork (follow_child=1, detach_fork=1) at ../../src/gdb/target.c:2220 #9 0x00000000005eda7a in follow_fork () at ../../src/gdb/infrun.c:493 (top-gdb) up #1 0x0000000000584aac in bkpt_remove_location (bl=0x10db740) at ../../src/gdb/breakpoint.c:13189 13189 return target_remove_breakpoint (bl->gdbarch, bp_tgt); (top-gdb) p bl->owner->type $8 = bp_step_resume > > From infrun.c:follow_fork: > > [...here 'tp' is the parent thread...] > if (follow_child && should_resume) > { > step_resume_breakpoint = clone_momentary_breakpoint > (tp->control.step_resume_breakpoint); > [...] > delete_step_resume_breakpoint (tp); > [...here bkpt has been removed from the parent...] It hasn't here no. This is all quite brittle. :-/ I think we should instead make the clone be disabled to begin with, so that it isn't marked as duplicate/inserted, and then re-enable it in follow_inferior_reset_breakpoints, _after_ it's been re_set to the child thread. -- Pedro Alves