* recurse.exp: watch on local variable that goes out of scope
@ 2004-07-20 14:37 Orjan Friberg
2004-07-20 19:37 ` Eli Zaretskii
0 siblings, 1 reply; 6+ messages in thread
From: Orjan Friberg @ 2004-07-20 14:37 UTC (permalink / raw)
To: gdb-patches
I'm having problems with recurse.exp on CRISv32 with hardware watchpoint support
- a local variable which goes out of scope isn't handled the same way as on the
i386 ("second instance watchpoint deleted when leaving scope"). On the i386
i386_stopped_data_address returns a proper address when I don't expect it to.
Here's a recap of what I think I've understood: in order to detect when a
watched local variable goes out of scope, gdb inserts a breakpoint on the
instruction where the function that the variable belongs to returns to. In this
case it shows up as ("maint info break"; local variable "b" is watched in
recurse (a=5)):
4 hw watchpoint keep y b
breakpoint already hit 2 times
-56 watchpoint scope del y 0x08048403 <recurse+51>
stop only in stack frame at 0xbffff4c4
breakpoint already hit 4 times
When stopped at the return statement of recurse (a=5), a continue is issued,
making recurse (a=5) return and the "watchpoint scope del" breakpoint is then
hit (the bp_addr argument to bpstat_stop_status == 0x08048403).
Now for the confusing part: bpstat_stop_status is called with
stopped_by_watchpoint == 1. This is because, at this point,
i386_stopped_data_address returns the address of the local variable "b" (the
address it had in recurse (a=5)), as if it were stopped due to a watchpoint hit.
I would have expected i386_stopped_data_address to return 0 at this point,
since it didn't stop due to a watchpoint hit. What am I missing here? Does
i386_stopped_data_address retain the stopped data address from the previous hit?
Thanks in advance.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: recurse.exp: watch on local variable that goes out of scope
2004-07-20 14:37 recurse.exp: watch on local variable that goes out of scope Orjan Friberg
@ 2004-07-20 19:37 ` Eli Zaretskii
2004-07-22 9:44 ` Orjan Friberg
0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2004-07-20 19:37 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
> Date: Tue, 20 Jul 2004 16:37:19 +0200
> From: Orjan Friberg <orjan.friberg@axis.com>
>
> Now for the confusing part: bpstat_stop_status is called with
> stopped_by_watchpoint == 1. This is because, at this point,
> i386_stopped_data_address returns the address of the local variable "b" (the
> address it had in recurse (a=5)), as if it were stopped due to a watchpoint hit.
> I would have expected i386_stopped_data_address to return 0 at this point,
> since it didn't stop due to a watchpoint hit. What am I missing here? Does
> i386_stopped_data_address retain the stopped data address from the previous hit?
No, it shouldn't return a stale address, it should return zero.
I reproduce the entire source of i386_stopped_data_address below; as
you see, it starts by zeroing out `addr' and assigns it a non-zero
value _only_ if I386_DR_WATCH_HIT(i) returns non-zero for some value
of i. This is supposed to query the debuggee about its debug
registers, and assumes that one of the debug registers will show that
a watchpoint has been hit only if a watchpoint has indeed been hit.
Can you step thru i386_stopped_data_address and see what exactly
happens there in your case?
CORE_ADDR
i386_stopped_data_address (void)
{
CORE_ADDR addr = 0;
int i;
dr_status_mirror = I386_DR_LOW_GET_STATUS ();
ALL_DEBUG_REGISTERS(i)
{
if (I386_DR_WATCH_HIT (i)
/* This second condition makes sure DRi is set up for a data
watchpoint, not a hardware breakpoint. The reason is
that GDB doesn't call the target_stopped_data_address
method except for data watchpoints. In other words, I'm
being paranoiac. */
&& I386_DR_GET_RW_LEN (i) != 0)
{
addr = dr_mirror[i];
if (maint_show_dr)
i386_show_dr ("watchpoint_hit", addr, -1, hw_write);
}
}
if (maint_show_dr && addr == 0)
i386_show_dr ("stopped_data_addr", 0, 0, hw_write);
return addr;
}
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: recurse.exp: watch on local variable that goes out of scope
2004-07-20 19:37 ` Eli Zaretskii
@ 2004-07-22 9:44 ` Orjan Friberg
2004-07-22 19:19 ` Eli Zaretskii
0 siblings, 1 reply; 6+ messages in thread
From: Orjan Friberg @ 2004-07-22 9:44 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
Eli Zaretskii wrote:
>
> No, it shouldn't return a stale address, it should return zero.
>
> I reproduce the entire source of i386_stopped_data_address below; as
> you see, it starts by zeroing out `addr' and assigns it a non-zero
> value _only_ if I386_DR_WATCH_HIT(i) returns non-zero for some value
> of i. This is supposed to query the debuggee about its debug
> registers, and assumes that one of the debug registers will show that
> a watchpoint has been hit only if a watchpoint has indeed been hit.
Bad wording on my part there; I didn't mean to assume that the function
i386_stopped_data_address itself retained the address, but that somehow the i386
watchpoint registers kept the last address and that was what was reported.
(Needless to say, I'm not intimately familiar with the i386 watchpoint registers.)
> Can you step thru i386_stopped_data_address and see what exactly
> happens there in your case?
Absolutely. The situation is the same as previously (watch on local variable b,
hit twice by the time we get to the return statement):
recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:20
20 return b;
(gdb) c
Continuing.
Breakpoint 4, i386_stopped_data_address () at ../../src/gdb/i386-nat.c:576
576 dr_status_mirror = I386_DR_LOW_GET_STATUS ();
Inside i386_stopped_data_address dr_status_mirror = 0xffff4ff1, which satisfies
the condition for I386_DR_WATCH_HIT (i) for i == 0. The reported address is
0xbffff488 (the address of local variable b).
Conversely, if I don't set the watchpoint on b until I reach the return
statement, the behaviour is what I expect: i386_stopped_data_address returns 0
when the watchpoint scope del breakpoint is hit. Notice the difference in the
following two sessions:
Mimicking recurse.exp
=====================
Breakpoint 1, recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:13
13 int b = 0;
(gdb) n
15 if (a == 1)
(gdb) watch b
Hardware watchpoint 8: b
(gdb) c
Continuing.
Hardware watchpoint 8: b
Old value = 0
New value = 5
recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:19
19 b *= recurse (a - 1);
(gdb) c
Continuing.
Hardware watchpoint 8: b
Old value = 5
New value = 120
recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:20
20 return b;
(gdb) maintenance info breakpoints
Num Type Disp Enb Address What
[snip]
-78 watchpoint scope del y 0x08048403 <recurse+51>
stop only in stack frame at 0xbffff4c4
breakpoint already hit 4 times
(gdb) c
Continuing.
Watchpoint 8 deleted because the program has left the block in
which its expression is valid.
0x08048403 in recurse (a=6) at ../../../src/gdb/testsuite/gdb.base/recurse.c:19
19 b *= recurse (a - 1);
(gdb)
Watch on return statement
=========================
Breakpoint 1, recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:13
13 int b = 0;
(gdb) until 20
recurse (a=5) at ../../../src/gdb/testsuite/gdb.base/recurse.c:20
20 return b;
(gdb) watch b
Hardware watchpoint 9: b
(gdb) maintenance info breakpoints
Num Type Disp Enb Address What
[snip]
-99 watchpoint scope del y 0x08048403 <recurse+51>
stop only in stack frame at 0xbffff4c4
(gdb) c
Continuing.
Hardware watchpoint 9 deleted because the program has left the block
in which its expression is valid.
Program exited normally.
(gdb)
I fail to see why these two cases should be different.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: recurse.exp: watch on local variable that goes out of scope
2004-07-22 9:44 ` Orjan Friberg
@ 2004-07-22 19:19 ` Eli Zaretskii
2004-07-23 9:23 ` Orjan Friberg
0 siblings, 1 reply; 6+ messages in thread
From: Eli Zaretskii @ 2004-07-22 19:19 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
> Date: Thu, 22 Jul 2004 11:44:09 +0200
> From: Orjan Friberg <orjan.friberg@axis.com>
>
> Breakpoint 4, i386_stopped_data_address () at ../../src/gdb/i386-nat.c:576
> 576 dr_status_mirror = I386_DR_LOW_GET_STATUS ();
>
> Inside i386_stopped_data_address dr_status_mirror = 0xffff4ff1, which satisfies
> the condition for I386_DR_WATCH_HIT (i) for i == 0. The reported address is
> 0xbffff488 (the address of local variable b).
So it sounds like your low-level target-side support misbehaves in
this case: I386_DR_LOW_GET_STATUS should map into a system call that
returns the contents of the DR6 debug register. If the returned value
says that one of the watched addresses was written to, there's nothing
GDB can do except report that and act accordingly.
> I fail to see why these two cases should be different.
Neither do I, but I'm not an expert for your target platform.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: recurse.exp: watch on local variable that goes out of scope
2004-07-22 19:19 ` Eli Zaretskii
@ 2004-07-23 9:23 ` Orjan Friberg
2004-07-28 15:52 ` Orjan Friberg
0 siblings, 1 reply; 6+ messages in thread
From: Orjan Friberg @ 2004-07-23 9:23 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
Eli Zaretskii wrote:
>
> So it sounds like your low-level target-side support misbehaves in
> this case: I386_DR_LOW_GET_STATUS should map into a system call that
> returns the contents of the DR6 debug register. If the returned value
> says that one of the watched addresses was written to, there's nothing
> GDB can do except report that and act accordingly.
Actually, this isn't an i386 remote target: it's my i386 Linux host. I'm sorry
if I sent you off in the wrong direction (I guess I should have been more
specific than just "i386").
Just to be clear on what the problem is: recurse.exp on an i386 Linux host is
all PASS; I just don't understand why it works the way it does.
There are actually two things that don't make sense to me:
1. Why the i386 reports a watchpoint hit when reaching the watchpoint scope del
breakpoint if the watchpoint has been hit previously (but not otherwise).
2. Compare the "Mimicking recurse.exp" and "Watch on return statement" examples
in my previous e-mail: in both cases GDB notices that the watched variable goes
out of scope, but stops only in the first case (where out of scope is detected
by watchpoint_check) and not in the second case (where out of scope is detected
by insert_bp_location).
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: recurse.exp: watch on local variable that goes out of scope
2004-07-23 9:23 ` Orjan Friberg
@ 2004-07-28 15:52 ` Orjan Friberg
0 siblings, 0 replies; 6+ messages in thread
From: Orjan Friberg @ 2004-07-28 15:52 UTC (permalink / raw)
To: gdb-patches; +Cc: Eli Zaretskii
Orjan Friberg wrote:
>
> Just to be clear on what the problem is: recurse.exp on an i386 Linux
> host is all PASS; I just don't understand why it works the way it does.
Hm, never mind (and sorry). recurse.exp runs fine now on my CRISv32 target
(with h/w breakpoints) after updating my tree.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-07-28 15:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-20 14:37 recurse.exp: watch on local variable that goes out of scope Orjan Friberg
2004-07-20 19:37 ` Eli Zaretskii
2004-07-22 9:44 ` Orjan Friberg
2004-07-22 19:19 ` Eli Zaretskii
2004-07-23 9:23 ` Orjan Friberg
2004-07-28 15:52 ` Orjan Friberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox