From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12787 invoked by alias); 14 Oct 2014 18:46:52 -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 12773 invoked by uid 89); 14 Oct 2014 18:46:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.3.2 X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 14 Oct 2014 18:46:50 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 502C011622C for ; Tue, 14 Oct 2014 14:46:48 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id KmJa-+L7nBFS for ; Tue, 14 Oct 2014 14:46:48 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 1F5EE11614F for ; Tue, 14 Oct 2014 14:46:48 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id F011440DC3; Tue, 14 Oct 2014 11:46:47 -0700 (PDT) Date: Tue, 14 Oct 2014 18:46:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: RFC: gdbserver crash on win XP during watchpoint removal Message-ID: <20141014184647.GB8879@adacore.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2014-10/txt/msg00358.txt.bz2 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: 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? Thanks! -- Joel