* [patch] Warn on constant value watchpoints
@ 2008-06-08 15:53 Jan Kratochvil
2008-06-08 18:05 ` Eli Zaretskii
0 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2008-06-08 15:53 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 201 bytes --]
Hi,
idea came from a discussion with the Firefox maintainer Martin Stransky who had
disfunctional watchpoint on the address of a variable:
(gdb) watch 0x4343548
Watchpoint 1: 70530376
Regards,
Jan
[-- Attachment #2: gdb-constant-watchpoint.patch --]
[-- Type: text/plain, Size: 3291 bytes --]
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* breakpoint.c (watch_command_1): New variable VAL_RESULT. Fill in
VAL_RESULT by the existing FETCH_WATCHPOINT_VALUE call. Ask user for
constant list VAL_RESULT.
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Set Watchpoints): Document constant value watchpoints.
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint.exp: New test for constant value watchpoints.
--- gdb/breakpoint.c 6 Jun 2008 20:58:08 -0000 1.324
+++ gdb/breakpoint.c 8 Jun 2008 15:18:38 -0000
@@ -5818,7 +5818,7 @@ watch_command_1 (char *arg, int accessfl
struct symtab_and_line sal;
struct expression *exp;
struct block *exp_valid_block;
- struct value *val, *mark;
+ struct value *val, *mark, *val_result;
struct frame_info *frame;
struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
@@ -5903,10 +5903,23 @@ watch_command_1 (char *arg, int accessfl
exp_end = arg;
exp_valid_block = innermost_block;
mark = value_mark ();
- fetch_watchpoint_value (exp, &val, NULL, NULL);
+ fetch_watchpoint_value (exp, &val, &val_result, NULL);
if (val != NULL)
release_value (val);
+ if (from_tty)
+ {
+ struct value *v;
+
+ /* VAL may be unset for unreachable final values. */
+ for (v = val_result; v; v = value_next (v))
+ if (VALUE_LVAL (v) == lval_memory || VALUE_LVAL (v) == lval_register)
+ break;
+ if (v == NULL && !query
+ (_("Do you insist on this watchpoint with a constant value? ")))
+ error (_("Watchpoint with a constant value was cancelled."));
+ }
+
tok = arg;
while (*tok == ' ' || *tok == '\t')
tok++;
--- gdb/doc/gdb.texinfo 6 Jun 2008 20:58:08 -0000 1.503
+++ gdb/doc/gdb.texinfo 8 Jun 2008 15:19:53 -0000
@@ -3375,6 +3426,18 @@ This command prints a list of watchpoint
it is the same as @code{info break} (@pxref{Set Breaks}).
@end table
+If you watch for a change in a numerically entered address you need to
+dereference it as the address itself is just a constant number which will never
+change:
+
+@smallexample
+(@value{GDBP}) watch 0x600850
+Do you insist on this watchpoint with a constant value? (y or n) n
+Watchpoint with a constant value was cancelled.
+(@value{GDBP}) watch *(int *) 0x600850
+Watchpoint 1: *(int *) 6293584
+@end smallexample
+
@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
watchpoints execute very quickly, and the debugger reports a change in
value at the exact instruction where the change occurs. If @value{GDBN}
--- gdb/testsuite/gdb.base/watchpoint.exp 15 Apr 2008 14:33:54 -0000 1.18
+++ gdb/testsuite/gdb.base/watchpoint.exp 8 Jun 2008 15:19:55 -0000
@@ -679,6 +679,18 @@ set prev_timeout $timeout
set timeout 600
verbose "Timeout now 600 sec.\n"
+# Test constant-value watchpoints.
+gdb_test "watch 123" "Watchpoint with a constant value was cancelled." \
+ "constant watchpoint" \
+ "Do you insist on this watchpoint with a constant value\\? \\(y or n\\) " \
+ "n"
+# For unsupported constant-value watchpoints catching we need to reset the
+# breakpoints counter.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
if [initialize] then {
test_simple_watchpoint
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-08 15:53 [patch] Warn on constant value watchpoints Jan Kratochvil
@ 2008-06-08 18:05 ` Eli Zaretskii
2008-06-08 18:09 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Eli Zaretskii @ 2008-06-08 18:05 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches
> Date: Sun, 8 Jun 2008 17:53:02 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
>
>
> --tKW2IUtsqtDRztdT
> Content-Type: text/plain; charset=us-ascii
> Content-Disposition: inline
>
> Hi,
>
> idea came from a discussion with the Firefox maintainer Martin Stransky who had
> disfunctional watchpoint on the address of a variable:
>
> (gdb) watch 0x4343548
> Watchpoint 1: 70530376
Should we allow such watchpoints? under what circumstances are they
useful?
> + if (v == NULL && !query
> + (_("Do you insist on this watchpoint with a constant value? ")))
I think a better text for this question would be
Really watch constant value %s?
> +If you watch for a change in a numerically entered address you need to
> +dereference it as the address itself is just a constant number which will never
> +change:
> +
> +@smallexample
> +(@value{GDBP}) watch 0x600850
> +Do you insist on this watchpoint with a constant value? (y or n) n
> +Watchpoint with a constant value was cancelled.
> +(@value{GDBP}) watch *(int *) 0x600850
> +Watchpoint 1: *(int *) 6293584
> +@end smallexample
Thanks, but please mention in the text that GDB asks for confirmation
because watching a constant value is not generally useful. Otherwise,
the example might not be fully understood.
Other than that, the patch for the manual is approved (assuming the
code is approved).
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-08 18:05 ` Eli Zaretskii
@ 2008-06-08 18:09 ` Daniel Jacobowitz
2008-06-08 18:50 ` Eli Zaretskii
0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2008-06-08 18:09 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: Jan Kratochvil, gdb-patches
On Sun, Jun 08, 2008 at 09:04:43PM +0300, Eli Zaretskii wrote:
> > (gdb) watch 0x4343548
> > Watchpoint 1: 70530376
>
> Should we allow such watchpoints? under what circumstances are they
> useful?
In my opinion, we should not allow such watchpoints.
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-08 18:09 ` Daniel Jacobowitz
@ 2008-06-08 18:50 ` Eli Zaretskii
2008-06-08 19:28 ` Jan Kratochvil
0 siblings, 1 reply; 11+ messages in thread
From: Eli Zaretskii @ 2008-06-08 18:50 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: jan.kratochvil, gdb-patches
> Date: Sun, 8 Jun 2008 14:09:09 -0400
> From: Daniel Jacobowitz <drow@false.org>
> Cc: Jan Kratochvil <jan.kratochvil@redhat.com>, gdb-patches@sourceware.org
>
> On Sun, Jun 08, 2008 at 09:04:43PM +0300, Eli Zaretskii wrote:
> > > (gdb) watch 0x4343548
> > > Watchpoint 1: 70530376
> >
> > Should we allow such watchpoints? under what circumstances are they
> > useful?
>
> In my opinion, we should not allow such watchpoints.
I agree. Does anyone disagree? If not, Jan, could you rework your
patch accordingly?
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-08 18:50 ` Eli Zaretskii
@ 2008-06-08 19:28 ` Jan Kratochvil
2008-06-09 6:14 ` Jan Kratochvil
0 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2008-06-08 19:28 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
[-- Attachment #1: Type: text/plain, Size: 692 bytes --]
On Sun, 08 Jun 2008 20:49:25 +0200, Eli Zaretskii wrote:
> > Date: Sun, 8 Jun 2008 14:09:09 -0400
> > From: Daniel Jacobowitz <drow@false.org>
> > Cc: Jan Kratochvil <jan.kratochvil@redhat.com>, gdb-patches@sourceware.org
> >
> > On Sun, Jun 08, 2008 at 09:04:43PM +0300, Eli Zaretskii wrote:
> > > > (gdb) watch 0x4343548
> > > > Watchpoint 1: 70530376
> > >
> > > Should we allow such watchpoints? under what circumstances are they
> > > useful?
> >
> > In my opinion, we should not allow such watchpoints.
>
> I agree. Does anyone disagree? If not, Jan, could you rework your
> patch accordingly?
I hope there is no longer any disagreement but requesting an approval.
Thanks,
Jan
[-- Attachment #2: gdb-constant-watchpoint2.patch --]
[-- Type: text/plain, Size: 3334 bytes --]
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* breakpoint.c (watch_command_1): New variable VAL_RESULT. Fill in
VAL_RESULT by the existing FETCH_WATCHPOINT_VALUE call. Refuse
constant VAL_RESULT list watchpoints.
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Set Watchpoints): Document constant value watchpoints.
2008-06-08 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint.exp: New test for constant value watchpoints.
--- gdb/breakpoint.c 6 Jun 2008 20:58:08 -0000 1.324
+++ gdb/breakpoint.c 8 Jun 2008 19:11:37 -0000
@@ -5818,7 +5818,7 @@ watch_command_1 (char *arg, int accessfl
struct symtab_and_line sal;
struct expression *exp;
struct block *exp_valid_block;
- struct value *val, *mark;
+ struct value *val, *mark, *val_result;
struct frame_info *frame;
struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
@@ -5903,10 +5903,28 @@ watch_command_1 (char *arg, int accessfl
exp_end = arg;
exp_valid_block = innermost_block;
mark = value_mark ();
- fetch_watchpoint_value (exp, &val, NULL, NULL);
+ fetch_watchpoint_value (exp, &val, &val_result, NULL);
if (val != NULL)
release_value (val);
+ /* VAL may be unset for unreachable final values. */
+ while (val_result != NULL)
+ {
+ if (VALUE_LVAL (val_result) == lval_memory
+ || VALUE_LVAL (val_result) == lval_register)
+ break;
+ val_result = value_next (val_result);
+ }
+ if (val_result == NULL)
+ {
+ int len;
+
+ len = exp_end - exp_start;
+ while (len > 0 && isspace (exp_start[len - 1]))
+ len--;
+ error (_("Cannot watch constant value %.*s."), len, exp_start);
+ }
+
tok = arg;
while (*tok == ' ' || *tok == '\t')
tok++;
--- gdb/doc/gdb.texinfo 6 Jun 2008 20:58:08 -0000 1.503
+++ gdb/doc/gdb.texinfo 8 Jun 2008 19:12:15 -0000
@@ -3375,6 +3375,17 @@ This command prints a list of watchpoint
it is the same as @code{info break} (@pxref{Set Breaks}).
@end table
+If you watch for a change in a numerically entered address you need to
+dereference it as the address itself is just a constant number which will never
+change. @value{GDBN} refuses to create a never invokable watchpoint:
+
+@smallexample
+(@value{GDBP}) watch 0x600850
+Cannot watch constant value 0x600850.
+(@value{GDBP}) watch *(int *) 0x600850
+Watchpoint 1: *(int *) 6293584
+@end smallexample
+
@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
watchpoints execute very quickly, and the debugger reports a change in
value at the exact instruction where the change occurs. If @value{GDBN}
--- gdb/testsuite/gdb.base/watchpoint.exp 15 Apr 2008 14:33:54 -0000 1.18
+++ gdb/testsuite/gdb.base/watchpoint.exp 8 Jun 2008 19:12:18 -0000
@@ -679,6 +679,17 @@ set prev_timeout $timeout
set timeout 600
verbose "Timeout now 600 sec.\n"
+# Test constant-value watchpoints.
+gdb_test "watch 123" "Cannot watch constant value 123." "constant watchpoint"
+gdb_test "watch 456 if 1 == 2" "Cannot watch constant value 456." \
+ "constant watchpoint with a condition"
+# For unsupported constant-value watchpoints catching we need to reset the
+# breakpoints counter.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
if [initialize] then {
test_simple_watchpoint
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-08 19:28 ` Jan Kratochvil
@ 2008-06-09 6:14 ` Jan Kratochvil
2008-06-26 15:01 ` Daniel Jacobowitz
0 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2008-06-09 6:14 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 239 bytes --]
On Sun, 08 Jun 2008 21:27:55 +0200, Jan Kratochvil wrote:
...
> I hope there is no longer any disagreement but requesting an approval.
Small update, while I see no countercase it should be more safe for future GDB
changes.
Regards,
Jan
[-- Attachment #2: gdb-constant-watchpoint3.patch --]
[-- Type: text/plain, Size: 3342 bytes --]
2008-06-09 Jan Kratochvil <jan.kratochvil@redhat.com>
* breakpoint.c (watch_command_1): New variable VAL_RESULT. Fill in
VAL_RESULT by the existing FETCH_WATCHPOINT_VALUE call. Refuse
constant VAL_RESULT list watchpoints.
2008-06-09 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Set Watchpoints): Document constant value watchpoints.
2008-06-09 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint.exp: New test for constant value watchpoints.
--- gdb/breakpoint.c 6 Jun 2008 20:58:08 -0000 1.324
+++ gdb/breakpoint.c 9 Jun 2008 06:00:53 -0000
@@ -5818,7 +5818,7 @@ watch_command_1 (char *arg, int accessfl
struct symtab_and_line sal;
struct expression *exp;
struct block *exp_valid_block;
- struct value *val, *mark;
+ struct value *val, *mark, *val_result;
struct frame_info *frame;
struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
@@ -5903,7 +5903,27 @@ watch_command_1 (char *arg, int accessfl
exp_end = arg;
exp_valid_block = innermost_block;
mark = value_mark ();
- fetch_watchpoint_value (exp, &val, NULL, NULL);
+ fetch_watchpoint_value (exp, &val, &val_result, NULL);
+
+ /* VAL may be unset for unreachable final values. */
+ while (val_result != NULL)
+ {
+ if (VALUE_LVAL (val_result) == lval_memory
+ || VALUE_LVAL (val_result) == lval_register)
+ break;
+ val_result = value_next (val_result);
+ }
+ if (val_result == NULL)
+ {
+ int len;
+
+ len = exp_end - exp_start;
+ while (len > 0 && isspace (exp_start[len - 1]))
+ len--;
+ error (_("Cannot watch constant value %.*s."), len, exp_start);
+ }
+
+ /* Break the VAL_RESULT values chain only after its check above. */
if (val != NULL)
release_value (val);
--- gdb/doc/gdb.texinfo 6 Jun 2008 20:58:08 -0000 1.503
+++ gdb/doc/gdb.texinfo 9 Jun 2008 06:01:37 -0000
@@ -3375,6 +3375,17 @@ This command prints a list of watchpoint
it is the same as @code{info break} (@pxref{Set Breaks}).
@end table
+If you watch for a change in a numerically entered address you need to
+dereference it as the address itself is just a constant number which will never
+change. @value{GDBN} refuses to create a never invokable watchpoint:
+
+@smallexample
+(@value{GDBP}) watch 0x600850
+Cannot watch constant value 0x600850.
+(@value{GDBP}) watch *(int *) 0x600850
+Watchpoint 1: *(int *) 6293584
+@end smallexample
+
@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
watchpoints execute very quickly, and the debugger reports a change in
value at the exact instruction where the change occurs. If @value{GDBN}
--- gdb/testsuite/gdb.base/watchpoint.exp 15 Apr 2008 14:33:54 -0000 1.18
+++ gdb/testsuite/gdb.base/watchpoint.exp 9 Jun 2008 06:01:40 -0000
@@ -679,6 +679,17 @@ set prev_timeout $timeout
set timeout 600
verbose "Timeout now 600 sec.\n"
+# Test constant-value watchpoints.
+gdb_test "watch 123" "Cannot watch constant value 123." "constant watchpoint"
+gdb_test "watch 456 if 1 == 2" "Cannot watch constant value 456." \
+ "constant watchpoint with a condition"
+# For unsupported constant-value watchpoints catching we need to reset the
+# breakpoints counter.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load $binfile
+
if [initialize] then {
test_simple_watchpoint
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-09 6:14 ` Jan Kratochvil
@ 2008-06-26 15:01 ` Daniel Jacobowitz
2008-06-26 19:40 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Daniel Jacobowitz @ 2008-06-26 15:01 UTC (permalink / raw)
To: Jan Kratochvil; +Cc: gdb-patches
On Mon, Jun 09, 2008 at 08:14:14AM +0200, Jan Kratochvil wrote:
> @@ -5903,7 +5903,27 @@ watch_command_1 (char *arg, int accessfl
> exp_end = arg;
> exp_valid_block = innermost_block;
> mark = value_mark ();
> - fetch_watchpoint_value (exp, &val, NULL, NULL);
> + fetch_watchpoint_value (exp, &val, &val_result, NULL);
> +
> + /* VAL may be unset for unreachable final values. */
> + while (val_result != NULL)
> + {
> + if (VALUE_LVAL (val_result) == lval_memory
> + || VALUE_LVAL (val_result) == lval_register)
> + break;
> + val_result = value_next (val_result);
> + }
val_result is the same as val, except possibly lazy. value_next
(val_result) will always be NULL, won't it? The chain goes the other
way - next from the oldest value (*val_chain argument, or the first
value after the saved mark).
If I'm right it seems like this patch will break "watch a + 1".
Also, I don't know how useful this feature is, but what happens with
"watch foo()"?
> + if (val_result == NULL)
> + {
> + int len;
> +
> + len = exp_end - exp_start;
> + while (len > 0 && isspace (exp_start[len - 1]))
> + len--;
> + error (_("Cannot watch constant value %.*s."), len, exp_start);
> + }
If an intermediate value could not be read, val_result may be NULL.
So this will stop us watching such expressions before they become
readable.
> +If you watch for a change in a numerically entered address you need to
> +dereference it as the address itself is just a constant number which will never
> +change. @value{GDBN} refuses to create a never invokable watchpoint:
never-changing?
--
Daniel Jacobowitz
CodeSourcery
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-26 15:01 ` Daniel Jacobowitz
@ 2008-06-26 19:40 ` Eli Zaretskii
2008-07-10 9:00 ` Jan Kratochvil
2008-07-10 9:02 ` Jan Kratochvil
2 siblings, 0 replies; 11+ messages in thread
From: Eli Zaretskii @ 2008-06-26 19:40 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: jan.kratochvil, gdb-patches
> Date: Thu, 26 Jun 2008 10:27:31 -0400
> From: Daniel Jacobowitz <drow@false.org>
> Cc: gdb-patches@sourceware.org
>
> > +If you watch for a change in a numerically entered address you need to
> > +dereference it as the address itself is just a constant number which will never
> > +change. @value{GDBN} refuses to create a never invokable watchpoint:
>
> never-changing?
"a watchpoint that watches a never-changing value"
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-26 15:01 ` Daniel Jacobowitz
2008-06-26 19:40 ` Eli Zaretskii
@ 2008-07-10 9:00 ` Jan Kratochvil
2008-07-10 9:02 ` Jan Kratochvil
2 siblings, 0 replies; 11+ messages in thread
From: Jan Kratochvil @ 2008-07-10 9:00 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
[-- Attachment #1: Type: text/plain, Size: 1121 bytes --]
On Thu, 26 Jun 2008 16:27:31 +0200, Daniel Jacobowitz wrote:
> On Mon, Jun 09, 2008 at 08:14:14AM +0200, Jan Kratochvil wrote:
> > @@ -5903,7 +5903,27 @@ watch_command_1 (char *arg, int accessfl
> > exp_end = arg;
> > exp_valid_block = innermost_block;
> > mark = value_mark ();
> > - fetch_watchpoint_value (exp, &val, NULL, NULL);
> > + fetch_watchpoint_value (exp, &val, &val_result, NULL);
> > +
> > + /* VAL may be unset for unreachable final values. */
> > + while (val_result != NULL)
> > + {
> > + if (VALUE_LVAL (val_result) == lval_memory
> > + || VALUE_LVAL (val_result) == lval_register)
> > + break;
> > + val_result = value_next (val_result);
> > + }
>
> val_result is the same as val, except possibly lazy. value_next
> (val_result) will always be NULL, won't it? The chain goes the other
> way - next from the oldest value (*val_chain argument, or the first
> value after the saved mark).
Thanks, a "typo" (it should have been the 3rd argument - VAL_CHAIN).
It had a regression on `watch **valpp' due to it.
This bug affected your other valid objections.
Thanks,
Jan
[-- Attachment #2: gdb-constant-watchpoint4.patch --]
[-- Type: text/plain, Size: 8823 bytes --]
2008-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* breakpoint.c (fetch_watchpoint_value): New comment on unreachable
values.
(watch_command_1): New variable VAL_CHAIN. Refuse constant watchpoints.
* gdbtypes.h (TYPE_CODE_FUNC): New comment regarding pointers to it.
2008-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Set Watchpoints): Document constant value watchpoints.
2008-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint.exp: Call TEST_CONSTANT_WATCHPOINT.
(test_constant_watchpoint): New function.
(test_inaccessible_watchpoint): Cleanup (delete) the watchpoint.
Test also a double-indirection watchpoint.
gdb.base/watchpoint.c (global_ptr_ptr): New variable.
(func4): New testing code for GLOBAL_PTR_PTR.
--- ./gdb/breakpoint.c 8 Jul 2008 11:09:40 -0000 1.330
+++ ./gdb/breakpoint.c 10 Jul 2008 08:19:07 -0000
@@ -824,7 +824,15 @@ is_hardware_watchpoint (struct breakpoin
If VAL_CHAIN is non-NULL, *VAL_CHAIN will be released from the
value chain. The caller must free the values individually. If
VAL_CHAIN is NULL, all generated values will be left on the value
- chain. */
+ chain.
+
+ Inferior unreachable values return:
+ Inferior `int *intp = NULL;' with `watch *intp':
+ *VALP is NULL, *RESULTP contains lazy LVAL_MEMORY address 0, *VAL_CHAIN
+ contains the *RESULTP element and also INTP as LVAL_MEMORY.
+ Inferior `int **intpp = NULL;' with `watch **intpp':
+ *VALP is NULL, *RESULTP is NULL, *VAL_CHAIN contains lazy LVAL_MEMORY
+ address 0 and also INTPP as LVAL_MEMORY. */
static void
fetch_watchpoint_value (struct expression *exp, struct value **valp,
@@ -5832,7 +5840,7 @@ watch_command_1 (char *arg, int accessfl
struct symtab_and_line sal;
struct expression *exp;
struct block *exp_valid_block;
- struct value *val, *mark;
+ struct value *val, *mark, *val_chain;
struct frame_info *frame;
struct frame_info *prev_frame = NULL;
char *exp_start = NULL;
@@ -5918,6 +5926,27 @@ watch_command_1 (char *arg, int accessfl
exp_valid_block = innermost_block;
mark = value_mark ();
fetch_watchpoint_value (exp, &val, NULL, NULL);
+
+ /* VALUE_MARK gets us the same value as FETCH_WATCHPOINT_VALUE's VAL_CHAIN
+ parameter. Just this way we do not have to VALUE_FREE the chained VALUEs
+ ourselves. */
+ for (val_chain = value_mark ();
+ val_chain != mark;
+ val_chain = value_next (val_chain))
+ if ((VALUE_LVAL (val_chain) == lval_memory
+ && TYPE_CODE (value_type (val_chain)) != TYPE_CODE_FUNC)
+ || VALUE_LVAL (val_chain) == lval_register)
+ break;
+ if (val_chain == mark)
+ {
+ int len;
+
+ len = exp_end - exp_start;
+ while (len > 0 && isspace (exp_start[len - 1]))
+ len--;
+ error (_("Cannot watch constant value %.*s."), len, exp_start);
+ }
+ /* Break the values chain only after its check above. */
if (val != NULL)
release_value (val);
--- ./gdb/gdbtypes.h 3 May 2008 22:20:13 -0000 1.87
+++ ./gdb/gdbtypes.h 10 Jul 2008 08:19:08 -0000
@@ -69,7 +69,22 @@ enum type_code
TYPE_CODE_UNION, /* C union or Pascal variant part */
TYPE_CODE_ENUM, /* Enumeration type */
TYPE_CODE_FLAGS, /* Bit flags type */
- TYPE_CODE_FUNC, /* Function type */
+
+ /* Function type. It is not a pointer to a function. Function reference
+ by its name (such as `printf') has this type. C automatically converts
+ this function type to a pointer to function for any operation except
+ `sizeof (function_type)' or `&function_type' (unary &).
+ `sizeof (function_type)' is undefined in C. But GCC provides extension
+ (info '(gcc)Pointer Arith') defining its size as 1 byte. DWARF does not
+ define its size but GDB defines the size the GCC compatible way - GDB
+ function MAKE_FUNCTION_TYPE. The address itself is not modifiable.
+ As the function type has size 1 but its real value has `sizeof
+ (CORE_ADDR)' we cannot use NOT_LVAL category because the address would
+ not fit in the VALUE_CONTENTS_RAW container of its VALUE. We use
+ LVAL_MEMORY (and its VALUE_ADDRESS field) for it but we must be careful
+ it is not lvalue, it is the only non-modifiable LVAL_MEMORY. */
+ TYPE_CODE_FUNC,
+
TYPE_CODE_INT, /* Integer type */
/* Floating type. This is *NOT* a complex type. Beware, there are parts
--- ./gdb/doc/gdb.texinfo 7 Jul 2008 12:05:30 -0000 1.506
+++ ./gdb/doc/gdb.texinfo 10 Jul 2008 08:19:37 -0000
@@ -3375,6 +3375,18 @@ This command prints a list of watchpoint
it is the same as @code{info break} (@pxref{Set Breaks}).
@end table
+If you watch for a change in a numerically entered address you need to
+dereference it as the address itself is just a constant number which will never
+change. @value{GDBN} refuses to create a watchpoint that watches
+a never-changing value:
+
+@smallexample
+(@value{GDBP}) watch 0x600850
+Cannot watch constant value 0x600850.
+(@value{GDBP}) watch *(int *) 0x600850
+Watchpoint 1: *(int *) 6293584
+@end smallexample
+
@value{GDBN} sets a @dfn{hardware watchpoint} if possible. Hardware
watchpoints execute very quickly, and the debugger reports a change in
value at the exact instruction where the change occurs. If @value{GDBN}
--- ./gdb/testsuite/gdb.base/watchpoint.c 3 Mar 2008 13:24:12 -0000 1.3
+++ ./gdb/testsuite/gdb.base/watchpoint.c 10 Jul 2008 08:19:39 -0000
@@ -40,6 +40,7 @@ struct foo struct1, struct2, *ptr1, *ptr
int doread = 0;
char *global_ptr;
+char **global_ptr_ptr;
void marker1 ()
{
@@ -118,6 +119,10 @@ func4 ()
buf[0] = 3;
global_ptr = buf;
buf[0] = 7;
+ buf[1] = 5;
+ global_ptr_ptr = &global_ptr;
+ buf[0] = 9;
+ global_ptr++;
}
int main ()
--- ./gdb/testsuite/gdb.base/watchpoint.exp 15 Apr 2008 14:33:54 -0000 1.18
+++ ./gdb/testsuite/gdb.base/watchpoint.exp 10 Jul 2008 08:19:41 -0000
@@ -644,7 +644,21 @@ proc test_watchpoint_and_breakpoint {} {
}
}
}
-
+
+proc test_constant_watchpoint {} {
+ global gdb_prompt
+
+ gdb_test "watch 5" "Cannot watch constant value 5." "number is constant"
+ gdb_test "watch marker1" "Cannot watch constant value marker1." \
+ "marker1 is constant"
+ gdb_test "watch count + 6" ".*atchpoint \[0-9\]+: count \\+ 6"
+ gdb_test "set \$expr_breakpoint_number = \$bpnum" ""
+ gdb_test "delete \$expr_breakpoint_number" ""
+ gdb_test "watch 7 + count" ".*atchpoint \[0-9\]+: 7 \\+ count"
+ gdb_test "set \$expr_breakpoint_number = \$bpnum" ""
+ gdb_test "delete \$expr_breakpoint_number" ""
+}
+
proc test_inaccessible_watchpoint {} {
global gdb_prompt
@@ -653,7 +667,8 @@ proc test_inaccessible_watchpoint {} {
if [runto func4] then {
gdb_test "watch *global_ptr" ".*atchpoint \[0-9\]+: \\*global_ptr"
- gdb_test "next" ".*global_ptr = buf.*"
+ gdb_test "set \$global_ptr_breakpoint_number = \$bpnum" ""
+ gdb_test "next" ".*global_ptr = buf.*" "global_ptr next"
gdb_test_multiple "next" "next over ptr init" {
-re ".*atchpoint \[0-9\]+: \\*global_ptr\r\n\r\nOld value = .*\r\nNew value = 3 .*\r\n.*$gdb_prompt $" {
# We can not test for <unknown> here because NULL may be readable.
@@ -666,6 +681,28 @@ proc test_inaccessible_watchpoint {} {
pass "next over buffer set"
}
}
+ gdb_test "delete \$global_ptr_breakpoint_number" ""
+ gdb_test "watch **global_ptr_ptr" ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr"
+ gdb_test "set \$global_ptr_ptr_breakpoint_number = \$bpnum" ""
+ gdb_test "next" ".*global_ptr_ptr = &global_ptr.*" "gloabl_ptr_ptr next"
+ gdb_test_multiple "next" "next over global_ptr_ptr init" {
+ -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = .*\r\nNew value = 7 .*\r\n.*$gdb_prompt $" {
+ # We can not test for <unknown> here because NULL may be readable.
+ # This test does rely on *NULL != 7.
+ pass "next over global_ptr_ptr init"
+ }
+ }
+ gdb_test_multiple "next" "next over global_ptr_ptr buffer set" {
+ -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 7 .*\r\nNew value = 9 .*\r\n.*$gdb_prompt $" {
+ pass "next over global_ptr_ptr buffer set"
+ }
+ }
+ gdb_test_multiple "next" "next over global_ptr_ptr pointer advance" {
+ -re ".*atchpoint \[0-9\]+: \\*\\*global_ptr_ptr\r\n\r\nOld value = 9 .*\r\nNew value = 5 .*\r\n.*$gdb_prompt $" {
+ pass "next over global_ptr_ptr pointer advance"
+ }
+ }
+ gdb_test "delete \$global_ptr_ptr_breakpoint_number" ""
}
}
@@ -833,6 +870,17 @@ if [initialize] then {
}
test_watchpoint_and_breakpoint
+
+ # See above.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+
+ test_constant_watchpoint
}
# Restore old timeout
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-06-26 15:01 ` Daniel Jacobowitz
2008-06-26 19:40 ` Eli Zaretskii
2008-07-10 9:00 ` Jan Kratochvil
@ 2008-07-10 9:02 ` Jan Kratochvil
2008-07-10 9:06 ` Jan Kratochvil
2 siblings, 1 reply; 11+ messages in thread
From: Jan Kratochvil @ 2008-07-10 9:02 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]
On Thu, 26 Jun 2008 16:27:31 +0200, Daniel Jacobowitz wrote:
> Also, I don't know how useful this feature is, but what happens with
> "watch foo()"?
Hmm, it crashes. A loop of:
#7736 call_function_by_hand (function=0xc7bcb0, nargs=0, args=0x7fffffffc528) at infcall.c:727
#7737 evaluate_subexp_standard (expect_type=0x0, exp=0xcb2f90, pos=0x7fffffffc9dc, noside=EVAL_NORMAL) at eval.c:1296
#7738 evaluate_subexp (expect_type=0x0, exp=0xcb2f90, pos=0x7fffffffc9dc, noside=EVAL_NORMAL) at eval.c:75
#7739 evaluate_expression (exp=0xcb2f90) at eval.c:165
#7740 gdb_evaluate_expression (exp=0xcb2f90, value=0x7fffffffca68) at wrapper.c:47
#7741 fetch_watchpoint_value (exp=0xcb2f90, valp=0x7fffffffcb18, resultp=0x7fffffffcb10, val_chain=0x7fffffffcb20) at breakpoint.c:844
#7742 update_watchpoint (b=0xc741c0, reparse=0) at breakpoint.c:937
#7743 insert_breakpoints () at breakpoint.c:1265
#7744 proceed (addr=18446744073709551615, siggnal=TARGET_SIGNAL_DEFAULT, step=0) at infrun.c:1229
This patch is the one I propose to be possibly accepted.
Regards,
Jan
[-- Attachment #2: gdb-watchpoint-loop-noisy.patch --]
[-- Type: text/plain, Size: 3165 bytes --]
2008-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* infrun.c (decrement_int): New function.
(proceed): Protect against looping from called INSERT_BREAKPOINTS.
2008-07-10 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/watchpoint.exp: Call TEST_WATCHPOINT_CALLING_INFERIOR.
(test_watchpoint_calling_inferior): New function.
--- ./gdb/infrun.c 8 Jul 2008 10:31:16 -0000 1.285
+++ ./gdb/infrun.c 9 Jul 2008 08:13:28 -0000
@@ -1146,6 +1146,15 @@ prepare_to_proceed (int step)
over calls to it and cleared when the inferior is started. */
static CORE_ADDR prev_pc;
+/* MAKE_CLEANUP stub. */
+static void
+decrement_int (void *arg)
+{
+ int *int_pointer = arg;
+
+ (*int_pointer)--;
+}
+
/* Basic routine for continuing the program in various fashions.
ADDR is the address to resume at, or -1 for resume where stopped.
@@ -1226,7 +1235,20 @@ proceed (CORE_ADDR addr, enum target_sig
or if we are stepping over one but we're using displaced stepping
to do so. */
if (! stepping_over_breakpoint || use_displaced_stepping (gdbarch))
- insert_breakpoints ();
+ {
+ struct cleanup *old_cleanups;
+ static int nested;
+
+ /* `watch func()' will nest as it will try to PROCEED to execute inferior
+ FUNC to complete UPDATE_WATCHPOINT. */
+ if (nested)
+ error (_("Aborting an inferior call used from a watchpoint"));
+
+ old_cleanups = make_cleanup (decrement_int, &nested);
+ nested++;
+ insert_breakpoints ();
+ do_cleanups (old_cleanups);
+ }
if (siggnal != TARGET_SIGNAL_DEFAULT)
stop_signal = siggnal;
--- ./gdb/testsuite/gdb.base/watchpoint.exp 15 Apr 2008 14:33:54 -0000 1.18
+++ ./gdb/testsuite/gdb.base/watchpoint.exp 9 Jul 2008 08:14:07 -0000
@@ -644,6 +644,33 @@ proc test_watchpoint_and_breakpoint {} {
}
}
}
+
+# Test a deadlock on an inferior call from a watchpoint.
+
+proc test_watchpoint_calling_inferior {} {
+ if [runto func3] then {
+ # Formerly GDB would deadlock while slowly allocating memory/stack.
+ global timeout
+ set prev_timeout $timeout
+ set timeout 10
+ verbose "Timeout now 10 sec.\n"
+
+ # Only hardware watchpoints cause the problem (in INSERT_BREAKPOINTS).
+ gdb_test "set can-use-hw-watchpoints 1" "" \
+ "Enable hw-watchpoint for a watchpoint with an inferior call"
+
+ gdb_test "watch func1()" "atchpoint \[0-9\]+: func1 \\(\\)" \
+ "Put a watchpoint with an inferior call"
+ gdb_breakpoint "func4"
+ # Either abort with `Aborting an inferior call used from a watchpoint'
+ # or it may get somehow resolved but we must get back a prompt.
+ gdb_test "continue" "" "Check the watchpoint with an inferior call"
+
+ # Restore old timeout
+ set timeout $prev_timeout
+ verbose "Timeout now $timeout sec.\n"
+ }
+}
proc test_inaccessible_watchpoint {} {
global gdb_prompt
@@ -833,6 +861,17 @@ if [initialize] then {
}
test_watchpoint_and_breakpoint
+
+ # See above.
+ if [istarget "mips-idt-*"] then {
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load $binfile
+ initialize
+ }
+
+ test_watchpoint_calling_inferior
}
# Restore old timeout
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [patch] Warn on constant value watchpoints
2008-07-10 9:02 ` Jan Kratochvil
@ 2008-07-10 9:06 ` Jan Kratochvil
0 siblings, 0 replies; 11+ messages in thread
From: Jan Kratochvil @ 2008-07-10 9:06 UTC (permalink / raw)
To: gdb-patches; +Cc: Daniel Jacobowitz
[-- Attachment #1: Type: text/plain, Size: 377 bytes --]
On Thu, 10 Jul 2008 11:02:07 +0200, Jan Kratochvil wrote:
> On Thu, 26 Jun 2008 16:27:31 +0200, Daniel Jacobowitz wrote:
> > Also, I don't know how useful this feature is, but what happens with
> > "watch foo()"?
>
> Hmm, it crashes.
Here is another patch - more simple but it will just silently watch missing
data, IMO wrong. Just a try to go the other way.
Regards,
Jan
[-- Attachment #2: gdb-watchpoint-loop-silent.patch --]
[-- Type: text/plain, Size: 1628 bytes --]
--- ./gdb/breakpoint.c 8 Jul 2008 11:09:40 -0000 1.330
+++ ./gdb/breakpoint.c 9 Jul 2008 06:14:26 -0000
@@ -841,7 +841,10 @@ fetch_watchpoint_value (struct expressio
/* Evaluate the expression. */
mark = value_mark ();
result = NULL;
- gdb_evaluate_expression (exp, &result);
+ /* We want GDB_EVALUATE_EXPRESSION but we also need EVAL_AVOID_SIDE_EFFECTS,
+ at least for a deadlock calling an inferior function in EXP which needs to
+ UPDATE_WATCHPOINT before its PROCEED. */
+ gdb_evaluate_type (exp, &result);
new_mark = value_mark ();
if (mark == new_mark)
return;
--- ./gdb/wrapper.c 17 Mar 2008 15:05:42 -0000 1.23
+++ ./gdb/wrapper.c 9 Jul 2008 06:14:33 -0000
@@ -44,7 +44,22 @@ gdb_evaluate_expression (struct expressi
TRY_CATCH (except, RETURN_MASK_ERROR)
{
- *value = evaluate_expression(exp);
+ *value = evaluate_expression (exp);
+ }
+
+ if (except.reason < 0)
+ return 0;
+ return 1;
+}
+
+int
+gdb_evaluate_type (struct expression *exp, struct value **value)
+{
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ *value = evaluate_type (exp);
}
if (except.reason < 0)
--- ./gdb/wrapper.h 1 Jan 2008 22:53:13 -0000 1.18
+++ ./gdb/wrapper.h 9 Jul 2008 06:14:33 -0000
@@ -29,6 +29,8 @@ extern int gdb_parse_exp_1 (char **, str
extern int gdb_evaluate_expression (struct expression *, struct value **);
+extern int gdb_evaluate_type (struct expression *, struct value **);
+
extern int gdb_value_fetch_lazy (struct value *);
extern int gdb_value_equal (struct value *, struct value *, int *);
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2008-07-10 9:06 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-08 15:53 [patch] Warn on constant value watchpoints Jan Kratochvil
2008-06-08 18:05 ` Eli Zaretskii
2008-06-08 18:09 ` Daniel Jacobowitz
2008-06-08 18:50 ` Eli Zaretskii
2008-06-08 19:28 ` Jan Kratochvil
2008-06-09 6:14 ` Jan Kratochvil
2008-06-26 15:01 ` Daniel Jacobowitz
2008-06-26 19:40 ` Eli Zaretskii
2008-07-10 9:00 ` Jan Kratochvil
2008-07-10 9:02 ` Jan Kratochvil
2008-07-10 9:06 ` Jan Kratochvil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox