* value.c (release_value): Clear 'next' pointer.
	* breakpoint.c (watch_command_1): Add 'just_location' argument.
	(watch_command_wrapper): Update.
	(watch_maybe_just_location): New function.
	(watch_command): Update.
	(rwatch_command_wrapper): Update.
	(rwatch_command): Update.
	(awatch_command_wrapper): Update.
	(awatch_command): Update.
	(check_for_argument): New function.
	(_initialize_breakpoint): Update help text.
gdb/testsuite
	* gdb.base/help.exp: Update.
	* gdb.base/watchpoint.exp (test_watchpoint_and_breakpoint): Delete
	watchpoint.
	(test_watch_location): New proc.
	(test_watchpoint_in_big_blob): Delete watchpoint.
	* gdb.base/watchpoint.c (func5): New function.
	(main): Call it.
gdb/doc
	* gdb.texinfo (Set Watchpoints): Document -location option.
This commit is contained in:
Tom Tromey 2010-08-16 19:19:22 +00:00
parent 70ebf4ed1a
commit 06a64a0b78
9 changed files with 159 additions and 25 deletions

View File

@ -1,3 +1,17 @@
2010-08-16 Tom Tromey <tromey@redhat.com>
* value.c (release_value): Clear 'next' pointer.
* breakpoint.c (watch_command_1): Add 'just_location' argument.
(watch_command_wrapper): Update.
(watch_maybe_just_location): New function.
(watch_command): Update.
(rwatch_command_wrapper): Update.
(rwatch_command): Update.
(awatch_command_wrapper): Update.
(awatch_command): Update.
(check_for_argument): New function.
(_initialize_breakpoint): Update help text.
2010-08-14 Ulrich Weigand <uweigand@de.ibm.com>
* arm-tdep.c (arm_push_dummy_call): Handle pointers to

View File

@ -98,8 +98,6 @@ static void clear_command (char *, int);
static void catch_command (char *, int);
static void watch_command (char *, int);
static int can_use_hardware_watchpoint (struct value *);
static void break_command_1 (char *, int, int);
@ -173,12 +171,6 @@ static void hbreak_command (char *, int);
static void thbreak_command (char *, int);
static void watch_command_1 (char *, int, int);
static void rwatch_command (char *, int);
static void awatch_command (char *, int);
static void do_enable_breakpoint (struct breakpoint *, enum bpdisp);
static void stop_command (char *arg, int from_tty);
@ -7995,7 +7987,7 @@ watchpoint_exp_is_const (const struct expression *exp)
hw_read: watch read,
hw_access: watch access (read or write) */
static void
watch_command_1 (char *arg, int accessflag, int from_tty)
watch_command_1 (char *arg, int accessflag, int from_tty, int just_location)
{
struct breakpoint *b, *scope_breakpoint = NULL;
struct expression *exp;
@ -8100,7 +8092,15 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
exp_valid_block = innermost_block;
mark = value_mark ();
fetch_subexp_value (exp, &pc, &val, NULL, NULL);
if (val != NULL)
if (just_location)
{
exp_valid_block = NULL;
val = value_addr (val);
release_value (val);
value_free_to_mark (mark);
}
else if (val != NULL)
release_value (val);
tok = arg;
@ -8202,7 +8202,24 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
b->exp = exp;
b->exp_valid_block = exp_valid_block;
b->cond_exp_valid_block = cond_exp_valid_block;
b->exp_string = savestring (exp_start, exp_end - exp_start);
if (just_location)
{
struct type *t = value_type (val);
CORE_ADDR addr = value_as_address (val);
char *name;
t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
name = type_to_string (t);
b->exp_string = xstrprintf ("* (%s *) %s", name,
core_addr_to_string (addr));
xfree (name);
/* The above expression is in C. */
b->language = language_c;
}
else
b->exp_string = savestring (exp_start, exp_end - exp_start);
b->val = val;
b->val_valid = 1;
if (cond_start)
@ -8229,7 +8246,8 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
scope_breakpoint->related_breakpoint = b;
}
value_free_to_mark (mark);
if (!just_location)
value_free_to_mark (mark);
/* Finally update the new watchpoint. This creates the locations
that should be inserted. */
@ -8319,37 +8337,73 @@ can_use_hardware_watchpoint (struct value *v)
void
watch_command_wrapper (char *arg, int from_tty)
{
watch_command (arg, from_tty);
watch_command_1 (arg, hw_write, from_tty, 0);
}
/* A helper function that looks for an argument at the start of a
string. The argument must also either be at the end of the string,
or be followed by whitespace. Returns 1 if it finds the argument,
0 otherwise. If the argument is found, it updates *STR. */
static int
check_for_argument (char **str, char *arg, int arg_len)
{
if (strncmp (*str, arg, arg_len) == 0
&& ((*str)[arg_len] == '\0' || isspace ((*str)[arg_len])))
{
*str += arg_len;
return 1;
}
return 0;
}
/* A helper function that looks for the "-location" argument and then
calls watch_command_1. */
static void
watch_maybe_just_location (char *arg, int accessflag, int from_tty)
{
int just_location = 0;
if (arg
&& (check_for_argument (&arg, "-location", sizeof ("-location") - 1)
|| check_for_argument (&arg, "-l", sizeof ("-l") - 1)))
{
ep_skip_leading_whitespace (&arg);
just_location = 1;
}
watch_command_1 (arg, accessflag, from_tty, just_location);
}
static void
watch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_write, from_tty);
watch_maybe_just_location (arg, hw_write, from_tty);
}
void
rwatch_command_wrapper (char *arg, int from_tty)
{
rwatch_command (arg, from_tty);
watch_command_1 (arg, hw_read, from_tty, 0);
}
static void
rwatch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_read, from_tty);
watch_maybe_just_location (arg, hw_read, from_tty);
}
void
awatch_command_wrapper (char *arg, int from_tty)
{
awatch_command (arg, from_tty);
watch_command_1 (arg, hw_access, from_tty, 0);
}
static void
awatch_command (char *arg, int from_tty)
{
watch_command_1 (arg, hw_access, from_tty);
watch_maybe_just_location (arg, hw_access, from_tty);
}
@ -11847,20 +11901,29 @@ With an argument, catch only exceptions with the given name."),
c = add_com ("watch", class_breakpoint, watch_command, _("\
Set a watchpoint for an expression.\n\
Usage: watch [-l|-location] EXPRESSION\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression changes."));
an expression changes.\n\
If -l or -location is given, this evaluates EXPRESSION and watches\n\
the memory to which it refers."));
set_cmd_completer (c, expression_completer);
c = add_com ("rwatch", class_breakpoint, rwatch_command, _("\
Set a read watchpoint for an expression.\n\
Usage: rwatch [-l|-location] EXPRESSION\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression is read."));
an expression is read.\n\
If -l or -location is given, this evaluates EXPRESSION and watches\n\
the memory to which it refers."));
set_cmd_completer (c, expression_completer);
c = add_com ("awatch", class_breakpoint, awatch_command, _("\
Set a watchpoint for an expression.\n\
Usage: awatch [-l|-location] EXPRESSION\n\
A watchpoint stops execution of your program whenever the value of\n\
an expression is either read or written."));
an expression is either read or written.\n\
If -l or -location is given, this evaluates EXPRESSION and watches\n\
the memory to which it refers."));
set_cmd_completer (c, expression_completer);
add_info ("watchpoints", watchpoints_info, _("\

View File

@ -1,3 +1,7 @@
2010-08-16 Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Set Watchpoints): Document -location option.
2010-08-13 Doug Evans <dje@google.com>
* gdb.texinfo (.debug_gdb_scripts section): Fix typo.

View File

@ -3711,7 +3711,7 @@ watchpoints, which do not slow down the running of your program.
@table @code
@kindex watch
@item watch @var{expr} @r{[}thread @var{threadnum}@r{]}
@item watch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{threadnum}@r{]}
Set a watchpoint for an expression. @value{GDBN} will break when the
expression @var{expr} is written into by the program and its value
changes. The simplest (and the most popular) use of this command is
@ -3728,13 +3728,22 @@ change the value of @var{expr}, @value{GDBN} will not break. Note
that watchpoints restricted to a single thread in this way only work
with Hardware Watchpoints.
Ordinarily a watchpoint respects the scope of variables in @var{expr}
(see below). The @code{-location} argument tells @value{GDBN} to
instead watch the memory referred to by @var{expr}. In this case,
@value{GDBN} will evaluate @var{expr}, take the address of the result,
and watch the memory at that address. The type of the result is used
to determine the size of the watched memory. If the expression's
result does not have an address, then @value{GDBN} will print an
error.
@kindex rwatch
@item rwatch @var{expr} @r{[}thread @var{threadnum}@r{]}
@item rwatch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{threadnum}@r{]}
Set a watchpoint that will break when the value of @var{expr} is read
by the program.
@kindex awatch
@item awatch @var{expr} @r{[}thread @var{threadnum}@r{]}
@item awatch @r{[}-l@r{|}-location@r{]} @var{expr} @r{[}thread @var{threadnum}@r{]}
Set a watchpoint that will break when @var{expr} is either read from
or written into by the program.

View File

@ -1,3 +1,13 @@
2010-08-16 Tom Tromey <tromey@redhat.com>
* gdb.base/help.exp: Update.
* gdb.base/watchpoint.exp (test_watchpoint_and_breakpoint): Delete
watchpoint.
(test_watch_location): New proc.
(test_watchpoint_in_big_blob): Delete watchpoint.
* gdb.base/watchpoint.c (func5): New function.
(main): Call it.
2010-08-16 Doug Evans <dje@google.com>
* gdb.python/python.exp: Fix syntax in "post event insertion" test.

View File

@ -669,7 +669,7 @@ test_class_help "user-defined" {
"Use the \"define\" command to define a command\.\[\r\n\]+"
}
# test help watch
gdb_test "help watch" "Set a watchpoint for an expression\.\[\r\n\]+A watchpoint stops execution of your program whenever the value of\[\r\n\]+an expression changes\." "help watch"
gdb_test "help watch" "Set a watchpoint for an expression\.\[\r\n\]+Usage: watch .-l.-location. EXPRESSION\[\r\n\]+A watchpoint stops execution of your program whenever the value of\[\r\n\]+an expression changes\.\[\r\n\]+If -l or -location is given, this evaluates EXPRESSION and watches\[\r\n\]+the memory to which it refers\." "help watch"
# test help whatis
gdb_test "help whatis" "Print data type of expression EXP\." "help whatis"
# test help where

View File

@ -126,6 +126,17 @@ func4 ()
global_ptr++;
}
void
func5 ()
{
int val = 0, val2 = 23;
int *x = &val;
/* func5 breakpoint here */
x = &val2;
val = 27;
}
int main ()
{
#ifdef usestubs
@ -203,5 +214,7 @@ int main ()
func4 ();
func5 ();
return 0;
}

View File

@ -615,6 +615,8 @@ proc test_watchpoint_and_breakpoint {} {
kfail "gdb/38" "next after watch x"
}
}
gdb_test_no_output "delete \$bpnum" "delete watch x"
}
}
@ -628,6 +630,19 @@ proc test_constant_watchpoint {} {
gdb_test_no_output "delete \$bpnum" "delete watchpoint `7 + count'"
}
proc test_watch_location {} {
gdb_breakpoint [gdb_get_line_number "func5 breakpoint here"]
gdb_continue_to_breakpoint "func5 breakpoint here"
gdb_test "watch -location *x" "atchpoint .*: .*" "watch -location .x"
gdb_test "continue" \
"Continuing.*\[Ww\]atchpoint .*: .*New value = 27.*" \
"continue with watch -location"
gdb_test_no_output "delete \$bpnum" "delete watch -location"
}
proc test_inaccessible_watchpoint {} {
global gdb_prompt
@ -678,6 +693,8 @@ proc test_watchpoint_in_big_blob {} {
gdb_test "watch buf" ".*atchpoint \[0-9\]+: buf"
gdb_test "cont" "Continuing.*atchpoint \[0-9\]+: buf\r\n\r\nOld value = .*testte\".*" "watchpoint on buf hit"
gdb_test_no_output "delete \$bpnum" "delete watch buf"
}
# Start with a fresh gdb.
@ -853,6 +870,8 @@ if [initialize] then {
}
test_constant_watchpoint
test_watch_location
}
# Restore old timeout

View File

@ -747,6 +747,7 @@ release_value (struct value *val)
if (all_values == val)
{
all_values = val->next;
val->next = NULL;
return;
}
@ -755,6 +756,7 @@ release_value (struct value *val)
if (v->next == val)
{
v->next = val->next;
val->next = NULL;
break;
}
}