Mail Archives: djgpp-workers/2009/06/09/11:07:56
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
X-Recipient: | djgpp-workers AT delorie DOT com
|
From: | "Pierre Muller" <muller AT ics DOT u-strasbg DOT fr>
|
To: | <djgpp-workers AT delorie DOT com>
|
Cc: | "'Eli Zaretskii'" <eliz AT gnu DOT org>
|
Subject: | Patch for windows watchpoint bug
|
Date: | Tue, 9 Jun 2009 17:06:21 +0200
|
Message-ID: | <001501c9e913$d9751830$8c5f4890$@u-strasbg.fr>
|
MIME-Version: | 1.0
|
X-Mailer: | Microsoft Office Outlook 12.0
|
Thread-Index: | AcnpE9a1pGndGs1hQl+q1ab1Fu7D7A==
|
X-Greylist: | Sender IP whitelisted, not delayed by milter-greylist-4.0.1 (mailhost.u-strasbg.fr [IPv6:2001:660:2402::151]); Tue, 09 Jun 2009 17:06:19 +0200 (CEST)
|
X-Virus-Scanned: | ClamAV 0.94.2/9444/Tue Jun 9 15:59:19 2009 on mr1.u-strasbg.fr
|
X-Virus-Status: | Clean
|
X-Spam-Status: | No, score=-100.0 required=5.0 tests=USER_IN_WHITELIST
|
| autolearn=disabled version=3.2.5
|
X-Spam-Checker-Version: | SpamAssassin 3.2.5 (2008-06-10) on mr1.u-strasbg.fr
|
Reply-To: | djgpp-workers AT delorie DOT com
|
Using more than one watchpoints doesn't work
on my Windows XP Pro SP3.
I found a way to fix this:
my patch simply splits the _clear_break_DPMI
into two parts, a first iteration over
the four possibly used watchpoint handles
to call __dpmi_get_state_of_debug_watchpoint
followed by a second iteration to disable the watchpoints
calling __dpmi_clear_debug_watchpoint.
I suspect that the Windows DPMI server
resets all watchpoint-hit bits as soon as a given watchpoint is disabled.
disabling the watchpoints in a second iteration
allows to avoid that bug. I don't think
that other DPMI servers that don't have this bug
should suffer from that code change.
Can be simply tested by
./gdb ./gdb
(gdb) set prompt top>
/* To avoid the problem of watchpoint to hardware watchpoint
promotion, start the debuggee first */
top> start
...
top> watch gdb_stderr
top> watch gdb_stdout
top> cont
And check that both watchpoints are correctly hit.
(without my patch, I get
a watchpoint hit on gdb_stdout, but
a SIGTRAP due to dr6 being found equal to 0
for the gdb_stderr watchpoint).
I also have a patch for v2.03, but
I don't know if this is still useful.
It might be for gdb 7.0
Pierre Muller
Index: dbgcom.c
===================================================================
RCS file: /cvs/djgpp/djgpp/src/debug/common/dbgcom.c,v
retrieving revision 1.28
diff -u -p -r1.28 dbgcom.c
--- dbgcom.c 9 Apr 2009 18:24:17 -0000 1.28
+++ dbgcom.c 9 Jun 2009 12:47:03 -0000
@@ -218,21 +218,27 @@ void load_npx (void)
asm volatile ("frstor %0" : "=m" (npx));
}
-static int _DPMIcancelBreak(int handle)
+static int _DPMIhitBreak(int handle)
{
int rv, state;
rv = __dpmi_get_state_of_debug_watchpoint(handle, &state);
if(rv == -1) {
printf("DPMI get watchpoint state failed for handle 0x%x\n",handle);
- state = 0;
+ return -1;
}
+ return (state & 1);
+}
+
+static int _DPMIcancelBreak(int handle)
+{
+ int rv;
+
rv = __dpmi_clear_debug_watchpoint(handle);
if(rv == -1)
printf("DPMI release watchpoint failed for handle 0x%x\n",handle);
- /* printf("CancelBreak han=0x%x returns state=0x%x\n",handle,state); */
- return (state & 1);
+ return (rv);
}
/* Can't be static because called in asm below; -O3 inlines if static */
@@ -277,7 +283,7 @@ void _set_break_DPMI(void)
void _clear_break_DPMI(void);
void _clear_break_DPMI(void)
{
- int i,bt;
+ int i,bt,res;
if(!nset) {
edi.dr[6] = 0;
@@ -288,10 +294,20 @@ void _clear_break_DPMI(void)
for(i=3;i>=0;i--) {
bt = bt << 1; /* Shift for next bit */
if(breakhandle[i] != -1)
- bt |= _DPMIcancelBreak(breakhandle[i]); /* Set low bit if active */
+ {
+ res = _DPMIhitBreak(breakhandle[i]); /* Set low bit if active */
+ if (res >=0)
+ bt |= res;
+ }
}
edi.dr[6] = bt;
+ for(i=3;i>=0;i--) {
+ bt = bt << 1; /* Shift for next bit */
+ if(breakhandle[i] != -1)
+ bt |= _DPMIcancelBreak(breakhandle[i]); /* Set low bit if active */
+ }
+
}
static __dpmi_paddr old_i31,old_i21,user_i31,user_i21;
- Raw text -