delorie.com/archives/browse.cgi   search  
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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019