Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@codesourcery.com>
To: "Philippe Waroquiers" <philippe.waroquiers@skynet.be>
Cc: gdb-patches@sourceware.org, yao@codesourcery.com
Subject: Re: x86 watchpoints bug (Re: ping: Re: PATCH : allow to set length of hw watchpoints (e.g. for Valgrind gdbserver))
Date: Tue, 31 May 2011 20:53:00 -0000	[thread overview]
Message-ID: <201105312153.06871.pedro@codesourcery.com> (raw)
In-Reply-To: <79AD3C71A83B4BCFBEE30A225231B3F9@soleil>

On Tuesday 31 May 2011 21:25:30, Philippe Waroquiers wrote:
> 
> > Not sure I understand what is different between GDB and GDBserver
> > here.  A watchpoint, from breakpoint.c's perpective can be composed
> > of several low-level watchpoints.  E.g., if the expression the user
> > wants to watch requires trapping accesses to two disjoint memory
> > regions for changes, each of those memory regions will correspond
> > to one low-level hardware watchpoint.  In GDBserver's or i386-nat.c's
> > perpective, there will be two watchpoints.  If the second fails to
> > insert, then breakpoint.c in GDB rolls back the first.  This applies
> > to GDBserver as well.
> 
> > ../../../src/gdb/gdbserver/linux-x86-low.c:511: A problem internal to GDBserver has been detected.
> > Assertion `DR_FIRSTADDR <= regnum && regnum < DR_LASTADDR' failed.
> 
> Sorry for the somewhat wrong analysis of the bug.

Not to worry.  Thanks for tripping on this. :-)

> 
> I have applied your patch in the assert, and tested again.
> The GDBserver does not crash anymore (but it still keeps a DR register
> busy for no reason).

Yes, that's a bug to fix too.  I'll need a bit to take a better
look at your patch.

> 
> So, there is for sure still a difference of behaviour (probably in breakpoint.c
> placing a "local" watch and a "remote" watch).

It looks to me the bug is equality present on native gdb:

$ ./gdb ~/s 
GNU gdb (GDB) 7.3.50.20110527-cvs
...
(gdb) start
Temporary breakpoint 1 at 0x4004b8: file s.c, line 22.
Starting program: /home/pedro/s 

Temporary breakpoint 1, main () at s.c:22
22         char * p = s1000;
(gdb) set breakpoint always-inserted on 
(gdb) maint set show-debug-regs on 
(gdb) watch s1
Hardware watchpoint 2: s1
During symbol reading, incomplete CFI data; unspecified registers (e.g., rax) at 0x4004e3.
insert_watchpoint (addr=609a08, len=1, type=data-write):
        CONTROL (DR7): 0000000000010101          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000609a08, ref.count=1  DR1: addr=0x0000000000000000, ref.count=0
        DR2: addr=0x0000000000000000, ref.count=0  DR3: addr=0x0000000000000000, ref.count=0
(gdb) watch s2
Hardware watchpoint 3: s2
insert_watchpoint (addr=60d8e8, len=2, type=data-write):
        CONTROL (DR7): 0000000000510105          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000609a08, ref.count=1  DR1: addr=0x000000000060d8e8, ref.count=1
        DR2: addr=0x0000000000000000, ref.count=0  DR3: addr=0x0000000000000000, ref.count=0
(gdb) watch s4
Hardware watchpoint 4: s4
insert_watchpoint (addr=607280, len=4, type=data-write):
        CONTROL (DR7): 000000000d510115          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000609a08, ref.count=1  DR1: addr=0x000000000060d8e8, ref.count=1
        DR2: addr=0x0000000000607280, ref.count=1  DR3: addr=0x0000000000000000, ref.count=0
(gdb) watch s3
Hardware watchpoint 5: s3
insert_watchpoint (addr=603768, len=3, type=data-write):
        CONTROL (DR7): 000000005d510155          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000609a08, ref.count=1  DR1: addr=0x000000000060d8e8, ref.count=1
        DR2: addr=0x0000000000607280, ref.count=1  DR3: addr=0x0000000000603768, ref.count=1
Warning:
Could not insert hardware watchpoint 5.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.

(gdb) del
Delete all breakpoints? (y or n) y
remove_watchpoint (addr=609a08, len=1, type=data-write):
        CONTROL (DR7): 000000005d510154          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000000000, ref.count=0  DR1: addr=0x000000000060d8e8, ref.count=1
        DR2: addr=0x0000000000607280, ref.count=1  DR3: addr=0x0000000000603768, ref.count=1
remove_watchpoint (addr=60d8e8, len=2, type=data-write):
        CONTROL (DR7): 000000005d510150          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000000000, ref.count=0  DR1: addr=0x0000000000000000, ref.count=0
        DR2: addr=0x0000000000607280, ref.count=1  DR3: addr=0x0000000000603768, ref.count=1
remove_watchpoint (addr=607280, len=4, type=data-write):
        CONTROL (DR7): 000000005d510140          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000000000, ref.count=0  DR1: addr=0x0000000000000000, ref.count=0
        DR2: addr=0x0000000000000000, ref.count=0  DR3: addr=0x0000000000603768, ref.count=1
(gdb) si
stopped_data_addr:
        CONTROL (DR7): 000000005d510140          STATUS (DR6): 0000000000004000
        DR0: addr=0x0000000000000000, ref.count=0  DR1: addr=0x0000000000000000, ref.count=0
        DR2: addr=0x0000000000000000, ref.count=0  DR3: addr=0x0000000000603768, ref.count=1
                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
23         for (i = 0; i < 1000; i++)
(gdb) 

You just didn't trip on the assert there, because there's no such
assertion on gdb (because I had never ported the
patch that had added the assertion to gdbserver, back to gdb.  I'll need to
remember to do that, in the name of keeping the codebases as much in
sync as possible...)

> 
> Note that there is another similar (but I believe correct) assert in the code, but 
> slightly different. I am not sure to understand why regnum validity is tested
> differently in the below:
>   if (! (regnum >= 0 && regnum <= DR_LASTADDR - DR_FIRSTADDR))
>     fatal ("Invalid debug register %d", regnum);

Yeah, just different spellings of the same thing.

-- 
Pedro Alves


  reply	other threads:[~2011-05-31 20:53 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-21 22:20 ping: Re: PATCH : allow to set length of hw watchpoints (e.g. for Valgrind gdbserver) Philippe Waroquiers
2011-05-26 19:02 ` Tom Tromey
2011-05-29 13:01   ` Philippe Waroquiers
2011-05-30 15:26     ` Joel Brobecker
2011-05-31 19:07     ` x86 watchpoints bug (Re: ping: Re: PATCH : allow to set length of hw watchpoints (e.g. for Valgrind gdbserver)) Pedro Alves
2011-05-31 20:25       ` Philippe Waroquiers
2011-05-31 20:53         ` Pedro Alves [this message]
2011-05-31 21:29       ` Pedro Alves
2011-05-31 22:15         ` Philippe Waroquiers
2011-05-31 23:04           ` Pedro Alves
2011-06-01 14:35             ` Pedro Alves
2011-06-08 22:55               ` Philippe Waroquiers
2011-06-09  0:00                 ` Pedro Alves
2011-06-09 22:16                   ` Philippe Waroquiers
2011-07-21 17:20                     ` Pedro Alves
2011-07-22 16:40                       ` Philippe Waroquiers
2011-07-22 16:43                         ` Pedro Alves
2011-07-23 16:28                           ` Thiago Jung Bauermann
2011-07-26 20:02                             ` software watchpoints bug (was: Re: x86 watchpoints bug) Pedro Alves
2011-07-27  3:45                               ` Thiago Jung Bauermann
2011-07-22 17:19                         ` x86 watchpoints bug (Re: ping: Re: PATCH : allow to set length of hw watchpoints (e.g. for Valgrind gdbserver)) Pedro Alves
2011-05-27  3:25 ` ping: Re: PATCH : allow to set length of hw watchpoints (e.g. for Valgrind gdbserver) Yao Qi
2011-05-27 17:53   ` Tom Tromey
2011-05-27 17:59     ` Pedro Alves
2011-05-30  4:06       ` Yao Qi
2011-05-30  5:34         ` Philippe Waroquiers
2011-05-30  5:48           ` Yao Qi
2011-05-30  6:31             ` Philippe Waroquiers
2011-05-31 17:31         ` Pedro Alves
2011-05-31 18:06           ` Philippe Waroquiers
2011-06-01 15:15             ` Pedro Alves
2011-06-05 20:55               ` Philippe Waroquiers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201105312153.06871.pedro@codesourcery.com \
    --to=pedro@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    --cc=philippe.waroquiers@skynet.be \
    --cc=yao@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox