From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 971 invoked by alias); 14 Oct 2014 19:23:34 -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 954 invoked by uid 89); 14 Oct 2014 19:23:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 14 Oct 2014 19:23:33 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s9EJNSPf022346 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 14 Oct 2014 15:23:29 -0400 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s9EJNRR1030981; Tue, 14 Oct 2014 15:23:28 -0400 Message-ID: <543D782F.10506@redhat.com> Date: Tue, 14 Oct 2014 19:23:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.1 MIME-Version: 1.0 To: Joel Brobecker , gdb-patches@sourceware.org Subject: Re: RFC: gdbserver crash on win XP during watchpoint removal References: <20141014184647.GB8879@adacore.com> In-Reply-To: <20141014184647.GB8879@adacore.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-SW-Source: 2014-10/txt/msg00366.txt.bz2 On 10/14/2014 07:46 PM, Joel Brobecker wrote: > Hello, > > I started investigating an issue that seems to only show up on Windows > XP, and only when debugging via GDBserver. I used the following code, > which matches the code in testsuite/gdb.ada/int_deref: > > with Pck; > > procedure Foo is > begin > Pck.Watch := Pck.Watch + 1; > end Foo; > > The test just breaks on line 5, just before the increment, inserts > a watchhpoint on it, and then continues: > > (gdb) b foo.adb:5 > Breakpoint 1 at 0x4017c2: file foo.adb, line 5. > (gdb) cont > Continuing. > > Breakpoint 1, foo () at foo.adb:5 > 5 Pck.Watch := Pck.Watch + 1; > (gdb) watch watch > Hardware watchpoint 2: watch > (gdb) c > Continuing. > Remote communication error. Target disconnected.: Invalid argument. > > The immediate cause for the communication error is easily explained, > gdbserver crashes due to a failed assertion: > > x86_remove_aligned_watchpoint: Assertion `state->dr_control_mirror == 0' failed. > > I think the assertion might be invalid, in this case. Turning debug > register traces on, I see: dr_control_mirror is never supposed to be updated from the target. It's a one way street - the state we _want_ dr7 to have on next resume. Where is this 0x400 coming from then? Also, what's different in native GDB? This debug registers code is shared between GDB and GDBserver now. Thanks, Pedro Alves > > insert_watchpoint (addr=000000000041c010, len=4, type=data-write): > CONTROL (DR7): 00000000000d0101 STATUS (DR6): 0000000000000000 > DR0: addr=0x0041c010, ref.count=1 DR1: addr=0x00000000, ref.count=0 > DR2: addr=0x00000000, ref.count=0 DR3: addr=0x00000000, ref.count=0 > stopped_data_addr: > CONTROL (DR7): 00000000000d0501 STATUS (DR6): 00000000ffff4ff0 > DR0: addr=0x0041c010, ref.count=1 DR1: addr=0x00000000, ref.count=0 > DR2: addr=0x00000000, ref.count=0 DR3: addr=0x00000000, ref.count=0 > watchpoint_hit (addr=000000000041c010, len=-1, type=data-write): > CONTROL (DR7): 00000000000d0501 STATUS (DR6): 00000000ffff4ff1 > DR0: addr=0x0041c010, ref.count=1 DR1: addr=0x00000000, ref.count=0 > DR2: addr=0x00000000, ref.count=0 DR3: addr=0x00000000, ref.count=0 > watchpoint_hit (addr=000000000041c010, len=-1, type=data-write): > CONTROL (DR7): 00000000000d0501 STATUS (DR6): 00000000ffff4ff1 > DR0: addr=0x0041c010, ref.count=1 DR1: addr=0x00000000, ref.count=0 > DR2: addr=0x00000000, ref.count=0 DR3: addr=0x00000000, ref.count=0 > > What's interesting is the value of DR7, which suddenly gets an extra > 0x400. So when we unset the bits we set before, we still that that > extra bit on the 10th bit. > > But looking at Intel documentation I have (IA-32 Intel Architecture > Software Developer's Manual - Volume 3), it says that bits 12-11-10 > are 001. > > I'm tempted to either clear those bits when reading the register value, > or else to mask those bits in the assertion. I feel that masking > those bits would be cleaner, since we'd carry a register value which > better matches reality. But the fact that this is working elsewhere > makes me wonder if we might actually be relying elsewhere on those bits > being zero, or maybe at least assuming that they are. > > Any thoughts before I send a patch?