Re: Hardware watchpoints

Eli Zaretskii
1999-10-20T07:02:00Z

> I wonder, would it be possible to watch expressions like foo.x by
> having can_use_hardware_watchpoint ignore lval_memory values which are
> still lazy? If a value is lazy, that means GDB never actually fetched
> it, but instead just used its address.

Could you suggest a quick hack to test whether this works? If so, I
could try to see if that solvces the problem (and whether it introduces
new ones ;-).

As far as I remember from when I looked at this issue,
can_use_hardware_watchpoint is not the only place where it comes into
play: the other place is where GDB actually inserts the watchpoints.
What happens there is that GDB asks to watch a region the size of the
whole struct (or array, as the case may be), and any reasonable
implementation will refuse that, at least on x86. (go32-nat.c has a
provision for watching up to 16-byte-long regions, but that's all.)

> Evaluating the expression foo.x, I think, produces two values: one for
> 'foo', which is lazy, and a second for the '.x' member of the first
> value, which is no longer lazy.

The question is: what happens for foo->x. Since foo can changein this
case, GDB has to watch both foo and foo->x. But it does NOT have to
watch *foo.
From jimb@cygnus.com Wed Oct 20 09:35:00 1999
From: Jim Blandy <jimb@cygnus.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: hjl@lucon.org (H.J. Lu), gdb@sourceware.cygnus.com
Subject: Re: Hardware watchpoints
Date: Wed, 20 Oct 1999 09:35:00 -0000
Message-id: <npvh82htxn.fsf@zwingli.cygnus.com>
References: <np3dv6k64w.fsf@zwingli.cygnus.com> <19991019235249.917DC1B494@ocean.lucon.org> <199910201401.KAA28719@mescaline.gnu.org>
X-SW-Source: 1999-q4/msg00067.html
Content-length: 2096

> > Evaluating the expression foo.x, I think, produces two values: one for
> > 'foo', which is lazy, and a second for the '.x' member of the first
> > value, which is no longer lazy.
>
> The question is: what happens for foo->x. Since foo can changein this
> case, GDB has to watch both foo and foo->x. But it does NOT have to
> watch *foo.

Evaluating foo->x, I believe the values on the chain would be foo (not
lazy), and foo->x (not lazy). So that would work correctly.

Even evaluating (*foo).x, I believe you'd get foo (not lazy), *foo
(lazy), and (*foo).x (not lazy). So that would work too.

>Could you suggest a quick hack to test whether this works? If so, I
>could try to see if that solvces the problem (and whether it introduces
>new ones ;-).

Here's an untested patch:

Index: breakpoint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/breakpoint.c,v
retrieving revision 1.251
diff -c -c -b -F'^(' -r1.251 breakpoint.c
*** breakpoint.c 1999/09/30 03:29:33 1.251
--- breakpoint.c 1999/10/20 16:34:30
***************
*** 858,864 ****
for (; v; v = v->next)
{
/* If it's a memory location, then we must watch it. */
! if (v->lval == lval_memory)
{
CORE_ADDR addr;
int len, type;
--- 858,865 ----
for (; v; v = v->next)
{
/* If it's a memory location, then we must watch it. */
! if (v->lval == lval_memory
! && ! v->lazy)
{
CORE_ADDR addr;
int len, type;
***************
*** 5050,5056 ****
hardware watchpoint for the constant expression. */
for (; v; v = v->next)
{
! if (v->lval == lval_memory)
{
CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
int len = TYPE_LENGTH (VALUE_TYPE (v));
--- 5051,5058 ----
hardware watchpoint for the constant expression. */
for (; v; v = v->next)
{
! if (v->lval == lval_memory
! && ! v->lazy)
{
CORE_ADDR vaddr = VALUE_ADDRESS (v) + VALUE_OFFSET (v);
int len = TYPE_LENGTH (VALUE_TYPE (v));
From capveg@cs.umd.edu Wed Oct 20 10:17:00 1999
From: Rob <capveg@cs.umd.edu>
To: "Peter.Schauer" <Peter.Schauer@Regent.E-Technik.TU-Muenchen.DE>
Cc: capveg@cs.umd.edu (Rob), gdb@sourceware.cygnus.com, capveg@cs.umd.edu
Subject: Re: fix to noexec_user_stack on solaris 2.{6,7}
Date: Wed, 20 Oct 1999 10:17:00 -0000
Message-id: <199910201715.NAA12493@xor.cs.umd.edu>
References: <199910200839.KAA17702@reisser.regent.e-technik.tu-muenchen.de>
X-SW-Source: 1999-q4/msg00068.html
Content-length: 1102

In message < 199910200839.KAA17702@reisser.regent.e-technik.tu-muenchen.de >, "Pe
ter.Schauer" writes:
>This will break calling of functions that return a structure or union.
>
>As per sparc calling conventions the call must looks like this:
>
> call fun,0
> nop
> unimp <size of returned struct>
>
>Setting CALL_DUMMY_LOCATION to AT_ENTRY_POINT doesn't handle this case.
>
>When I was looking at the problem a long time ago, I had no idea how to
>solve it properly.

Just so I am clear on how this breaks:
gdb successfully makes the call and returns, but if the return type
is a struct or union, the size is not correctly reported. With an
incorrect size, you can look into the internals of the struct.

Is that right? If so, I think I am just going to apply the patch to my
systems, and be done with it. (Read: "users be damned" :)

Does anyone have any good pointers to information on Sparc calling
conventions?
I have the "Sparc Assembly Reference Manual" that comes with the big solaris
documentation set, but I find it relatively useless.

Thanks for the help,

- Rob
.