aboutsummaryrefslogtreecommitdiff
path: root/gdb/breakpoint.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2009-11-21 21:17:17 +0000
committerPedro Alves <palves@redhat.com>2009-11-21 21:17:17 +0000
commitf6bc20088048522ffb945254f59f824f5cbdaebd (patch)
tree88a4983875865ce7d3659f85c5628703923eb225 /gdb/breakpoint.c
parent8c2fb5deb3f40d81b448d54d7eaa02cde2c6e014 (diff)
downloadgdb-f6bc20088048522ffb945254f59f824f5cbdaebd.zip
gdb-f6bc20088048522ffb945254f59f824f5cbdaebd.tar.gz
gdb-f6bc20088048522ffb945254f59f824f5cbdaebd.tar.bz2
gdb/
* breakpoint.h (struct breakpoint) <watchpoint_thread>: New field. * breakpoint.c (watchpoint_in_thread_scope): New. (update_watchpoint): Skip if the local watchpoint's thread doesn't match the current thread, or if the current thread is running. (watchpoint_check): Ditto. (watch_command_1): Set the watchpoint's watchpoint_thread field. gdb/testsuite/ * gdb.threads/local-watch-wrong-thread.c, gdb.threads/local-watch-wrong-thread.exp: New files.
Diffstat (limited to 'gdb/breakpoint.c')
-rw-r--r--gdb/breakpoint.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index bca923e..510399f 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -985,6 +985,24 @@ fetch_watchpoint_value (struct expression *exp, struct value **valp,
}
}
+/* Assuming that B is a watchpoint: returns true if the current thread
+ and its running state are safe to evaluate or update watchpoint B.
+ Watchpoints on local expressions need to be evaluated in the
+ context of the thread that was current when the watchpoint was
+ created, and, that thread needs to be stopped to be able to select
+ the correct frame context. Watchpoints on global expressions can
+ be evaluated on any thread, and in any state. It is presently left
+ to the target allowing memory accesses when threads are
+ running. */
+
+static int
+watchpoint_in_thread_scope (struct breakpoint *b)
+{
+ return (ptid_equal (b->watchpoint_thread, null_ptid)
+ || (ptid_equal (inferior_ptid, b->watchpoint_thread)
+ && !is_executing (inferior_ptid)));
+}
+
/* Assuming that B is a watchpoint:
- Reparse watchpoint expression, if REPARSE is non-zero
- Evaluate expression and store the result in B->val
@@ -1043,6 +1061,12 @@ update_watchpoint (struct breakpoint *b, int reparse)
bpstat bs;
struct program_space *frame_pspace;
+ /* If this is a local watchpoint, we only want to check if the
+ watchpoint frame is in scope if the current thread is the thread
+ that was used to create the watchpoint. */
+ if (!watchpoint_in_thread_scope (b))
+ return;
+
/* We don't free locations. They are stored in bp_location array and
update_global_locations will eventually delete them and remove
breakpoints if needed. */
@@ -3124,6 +3148,12 @@ watchpoint_check (void *p)
b = bs->breakpoint_at->owner;
+ /* If this is a local watchpoint, we only want to check if the
+ watchpoint frame is in scope if the current thread is the thread
+ that was used to create the watchpoint. */
+ if (!watchpoint_in_thread_scope (b))
+ return WP_VALUE_NOT_CHANGED;
+
if (b->exp_valid_block == NULL)
within_current_scope = 1;
else
@@ -7190,9 +7220,15 @@ watch_command_1 (char *arg, int accessflag, int from_tty)
b->cond_string = 0;
if (frame)
- b->watchpoint_frame = get_frame_id (frame);
+ {
+ b->watchpoint_frame = get_frame_id (frame);
+ b->watchpoint_thread = inferior_ptid;
+ }
else
- b->watchpoint_frame = null_frame_id;
+ {
+ b->watchpoint_frame = null_frame_id;
+ b->watchpoint_thread = null_ptid;
+ }
if (scope_breakpoint != NULL)
{