This is the mail archive of the
mailing list for the GDB project.
Re: read watchpoints ignored?
- From: Daniel Jacobowitz <drow at false dot org>
- To: Eli Zaretskii <eliz at gnu dot org>
- Cc: Vladimir Prus <ghost at cs dot msu dot su>, gdb at sources dot redhat dot com
- Date: Sun, 13 Nov 2005 11:45:48 -0500
- Subject: Re: read watchpoints ignored?
- References: <email@example.com> <firstname.lastname@example.org>
On Fri, Nov 11, 2005 at 08:19:41PM +0200, Eli Zaretskii wrote:
> > (gdb) b main
> > Breakpoint 1 at 0x80483a4: file rw.cpp, line 8.
> > (gdb) r
> > Starting program: /tmp/a.out
> > Breakpoint 1, main () at rw.cpp:8
> > 8 a = 10;
> > (gdb) rwatch a
> > Hardware read watchpoint 2: a
> > (gdb) c
> > Continuing.
> > Hardware read watchpoint 2: a
> > Value = 10
> > 0x080483bd in main () at rw.cpp:11
> > 11 c = a;
> > Expected result: gdb stops on "b = a" line.
> > Actual result: gdb stops on "c = a".
I can reproduce this on Debian/unstable.
> On Debian GNU/Linux, I can reproduce the problem, but it seems that it
> is a side effect of another problem: the breakpoint set by "b main"
> stops the program too late. Observe:
You included an example of setting the breakpoint by address, but not
one of setting by "b main", so I can't guess from your transcript what
happened. You also didn't show the disassembly of the function. To
answer your question, GDB sets breakpoints on functions based on a
combination of prologue analysis and debug info.
Here's what mine looks like (note, this is x86_64, not i386):
0x00000000004004a8 <main+0>: push %rbp
0x00000000004004a9 <main+1>: mov %rsp,%rbp
0x00000000004004ac <main+4>: movl $0xa,1049662(%rip) # 0x5008f4 <a>
0x00000000004004b6 <main+14>: mov $0x40061c,%edi
0x00000000004004bb <main+19>: callq 0x4003e0 <puts@plt>
0x00000000004004c0 <main+24>: mov 1049646(%rip),%eax # 0x5008f4 <a>
0x00000000004004c6 <main+30>: mov %eax,1049632(%rip) # 0x5008ec <b>
0x00000000004004cc <main+36>: mov 1049634(%rip),%eax # 0x5008f4 <a>
0x00000000004004d2 <main+42>: mov %eax,1049624(%rip) # 0x5008f0 <c>
0x00000000004004d8 <main+48>: mov $0x0,%eax
0x00000000004004dd <main+53>: leaveq
0x00000000004004de <main+54>: retq
"break main" sets the breakpoint at main+4. Which I'd expect, really -
it's after the stack frame is created.
> ~$ gdb ./rwt
> GNU gdb 6.1-debian
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for details.
> This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1".
This is a relatively old GDB, and so probably a relatively old GCC. On
my installation it behaves as reported.
> So I'm guessing that the problem happens because GDB misses the data
> write into a in line 7, and thus doesn't take notice that a was
> assigned the value 10. That's why it gets confused when "b = a;"
> reads from a.
It misses it, but shouldn't. When GDB single steps over the
temporarily removed breakpoint at "main", it is not updating the values
of watchpoints before resuming the instruction. That instruction
happened to modify the value behind a read watchpoint.
Presumably because trap_expected is set, infrun never calls
bpstat_stop_status, so the watchpoint is never checked. Maybe we
should separate that code out into a separate function, or maybe we
should call it more rigorously.
> No, I don't think so. The theory behind the read watchpoint support
> on x86 is that GDB should also see the data writes into the watched
> variable, and thus always track its current value. This is because
> x86 debug hardware doesn't support read watchpoints, it only supports
> data-write watchpoints and access (read or write) watchpoints. So GDB
> _emulates_ read watchpoints on x86 by setting an access watchpoint,
> and monitoring value changes with the code you presented above.
> Access watchpoint should trigger when the address is written by the
> "a = 10;" line, at which point GDB should get control, record the new
> value, then continue the debuggee without announcing the watchpoint
> (since the value changed). Later, when "b = a;" reads from a, the
> access watchpoint fires again, but this time the value didn't change,
> so the watchpoint should be announced.
Eli, am I reading breakpoint.c right? It looks like we _always_ ignore
changed values for bp_read_watchpoint, which means that the core of GDB
does not work on targets which support true read watchpoints. Which
IIRC includes S/390, which disabled them for this reason.
This should be controlled by an architecture method indicating that
there are only access watchpoints.
> Here's the GDB session on MS-Windows. As you see, "b main" stops at
> line 6, the opening brace of the main function, and then the
> watchpoint works as you expected.
Probably Windows code requires an additional instruction before "a" can
be written to, so you are not stopped on the store instruction as in my