* [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